<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  <meta name="author" content="makumba-dev group">
  <title>Makumba Specification</title>
  <link rel="stylesheet" type="text/css" media="all" href="main.css">
  <script type="text/javascript" src="main.js"></script>
  <script type="text/javascript" src="tabs.js"></script>
</head>
<body>
<script type="text/javascript">
   makeNavBar("");
</script>

<div class="pageFooter"><font color="red">This documentation is outdated, please visit <a href="http://new.makumba.org">http://new.makumba.org</a> for an up-to-date reference documentation.</font></div>
<h1>Makumba Specification</h1>

<div class="menu">
  <span class="menu_item"><a class="tab icon_expand" name="tabmenu_expand" href="#tab_expand" title="Expand all tabs and show them together (one after other, good for printing and searching)">&nbsp;</a></span> |
  <span class="menu_item"> <a class="tab" name="tabmenu" href="#tab_dd" title="...writing MDDs"><b>[Data Definitions]</b></a></span>
  <span class="menu_item"> <a class="tab" name="tabmenu" href="#tab_ql" title="...getting data from the database"><b>[Query Languages]</b></a></span>
  <span class="menu_item"> <a class="tab" name="tabmenu" href="#tab_queryFragments" title="...MDD Functions & authorisation"><b>[Query Fragments]</b></a></span>
  <b><span title="...viewing/editing data though HTML pages">[JSP tag library</span>:</b>
  <span class="menu_item"> <a class="tab" name="tabmenu" href="#tab_intro" title="...controller &amp; response"><b>Intro</b></a></span>| 
  <span class="menu_item"> <a class="tab" name="tabmenu" href="#tab_list" title="...viewing data through HTML pages"><b>Listing</b></a></span>|
  <span class="menu_item"> <a class="tab" name="tabmenu" href="#tab_forms" title="...editing data through HTML pages"><b>Forms</b></a></span>|
  <span class="menu_item"> <a class="tab" name="tabmenu" href="#tab_search" title="...searching in data through HTML pages"><b>Search</b></a>]</span>
  <span class="menu_item"> <a class="tab" name="tabmenu" href="#tab_bl" title="...adding logic to basic operations"><b>[Business Logics]</b></a></span>
  <span class="menu_item"> <a class="tab" name="tabmenu" href="#tab_summary" title="...Presentation and internal representation principles"><b>[Summary]</b></a></span>
</div>





<div id="tab_dd" class="content">
<h2><a name="Data_Description">Data Definition Language</a></h2>
<table width="100%">
  <tr>
    <td valign="top">
    <div class="navbarPage">
    <ul class="navbarPage">
      <li class="section"><a href="#Types_objects_databases">Types, objects, databases</a></li>
      <li class="section"><a href="#Fields">Fields</a></li>
      <li class="section"><a href="#DefaultFields">Default fields</a></li>
      <li class="section"><a href="#SimpleFieldTypes">Simple&nbsp;field&nbsp;types</a>
      <ul class="navbarPage">
        <li class="sectionLevel2"><a href="#int">int</a></li>
        <li class="sectionLevel2"><a href="#real">real</a></li>
        <li class="sectionLevel2"><a href="#char">char</a></li>
        <li class="sectionLevel2"><a href="#boolean">boolean</a></li>
        <li class="sectionLevel2"><a href="#text">text</a></li>
        <li class="sectionLevel2"><a href="#binary">binary</a></li>
        <li class="sectionLevel2"><a href="#date">date</a></li>
      </ul>
      </li>
      <li class="section"><a href="#StructuralTypes">Structural (relational) types</a>
      <ul class="navbarPage">
        <li class="sectionLevel2"><a href="#ptr">ptr</a></li>
        <li class="sectionLevel2"><a href="#set">set</a></li>
        <li class="sectionLevel2"><a href="#file">file</a></li>
      </ul>
      </li>
      <li class="section"><a href="#MacroTypes">Macro types</a></li>
      <li class="section"><a href="#FieldAttributes">Field attributes</a></li>
      <li class="section"><a href="#ObjectTitle">Object title</a></li>
      <li class="section"><a href="#Include">Include mechanism</a></li>
      <li class="section"><a href="#validation">Validation definition</a>
      <ul class="navbarPage">
        <li class="sectionLevel2"><a href="#range">Range</a></li>
        <li class="sectionLevel2"><a href="#stringLength">String lenght</a></li>
        <li class="sectionLevel2"><a href="#regexp">Regular expressions</a></li>
        <li class="sectionLevel2"><a href="#comparison">Comparison</a></li>
        <li class="sectionLevel2"><a href="#multiFielUnique">Multi-field uniqueness</a></li>
      </ul>
      </li>

    </ul>
    </div>
    </td>
    <td>(the Makumba abstract level)
    <h3><a name="Types_objects_databases">Types, objects, databases</a></h3>
    <p>Data definitions describe <b>data types (or classes)</b>. They are placed in files contained in directory
    hierarchies, and the directory name is part of the type name (similar to Java packages). For example <b>the file
    best/Student.mdd </b>describes<b> the type best.Student</b>. Type names can contain letters, digits, underscores and
    dashes and cannot contain slashes and dots.<!-- MDD max size 255 : http://bugs.best.eu.org/show_bug.cgi?id=639 -->
    Usually, the directories are used to separate organisations and projects.</p>

    <div class="note">Current Java implementation finds the data definition files as follows: <!-- FIXME: is this still correct? Bug 602 -->
    <ul>
      <li>the designated file extension is <code>.mdd</code> (Makumba Data Definition)</li>
      <li>relative to CLASSPATH (e.g. <code>classes/best/Student.mdd</code>)</li>
      <li>in a directory called "<b>dataDefinitions/</b>" in the CLASSPATH (e.g. <code>classes/dataDefinitions/best/Student.mdd</code>)</li>
      <li class="oldfeat">OLDSTYLE: if no mdd file is present, the no-extension file (i.e. best/Student) is looked
      up</li>
    </ul>
    </div>
    <p><b>Data objects (records)</b> are stored in <b>databases</b>.</p>
    <p>The actual implementation of the database is not part of this specification but implementation suggestions
    will be made. <b>Data can be copied and/or replicated between different databases</b>, even between different DB
    engine types.</p>
    <div class="futfeat note">Replication is not yet implemented, but the design is prepared for it. Copying
    works.</div>
    <h3><a name="Fields">Fields</a></h3>
    <p>Every data definition file contains <b>field definitions</b>, separated by newline.</p>
    <p>A field definition looks like:</p>
    <pre class="example"><b>fieldname= [attributes] fieldtype [parameters] [; description]</b></pre>
    <p>&nbsp;</p>
    <div class="note futfeat">default values are supported internally, but not by the mdd parser</div>
    <div class="internals note">As an implementation guideline, field names tend to stay approximately the same
    in:
    <ul>
      <li>http requests</li>
      <li>Record instances (<a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/Dictionary.html">java.util.Dictionary</a> in the current Java API)</li>
      <li>database columns</li>
      <li>etc</li>
    </ul>
    </div>
    <p class="futfeat">(Automatic labeling: The field description might be used at interface levels to present that
    field. It is typically shown at the left of, or somewhere near to, the input control (text box, radio button,
    chooser, etc) that allows for data input in that field. If a field description is not present, its field name stands
    for its description by default.)</p>
    <p><b>Comment lines</b> can be inserted in the data definition files as follows:</p>
    <pre class="example"><b>#</b> <i>your comment...</i></pre>
    <h3><a name="DefaultFields">Default fields</a></h3>
    <p>Every datatype has some additional fields by default, as follows:</p>
    <ul>
      <li>Primary Key field, consisting of two parts [DBSV with 8 bits | UID with 24 bits]:
      <ul>
        <li>Database identifier (DBSV). It is unique (within the webapp) per database. All objects created thru
        that webapp and in that database get the same value. It is set by property dbsv in the database config file.</li>
        <li>Object identifier (UID): unique id for the object in the given database.</li>
      </ul>
      <br>
      This combination ensures that no two objects of one type have the same primary key field. See <a
        href="SQL-drivers.html#ConfigProperties">how to configure</a> this.<br>
      The name of the primary key field is the same with the last part of the type name. If another field by that name
      is defined by the makumba user, this field will be renamed in the database.</li>
      <li>Object creation time
      <div class="note">Can be accessed as TS_create.</div>
      </li>
      <li>Last modification time. Updates whenever the object is changed. The initicial value is TS_create.
      <div class="note">Can be accessed as TS_modify.</div>
      </li>
    </ul>
    <h3><a name="SimpleFieldTypes">Simple field types</a></h3>
    <h4><a name="int">int</a></h4>
    <p>A 32-bit integer. For example</p>
    <pre class="example">shoeSize= int; Shoe size<br></pre>
    <p>If the int can have a limited number of values, it can be described as follows</p>
    <pre class="example">gender= int{ "male"=0, "female"=1 }; Sex<br></pre>
    <p>This will help the presentation layer to present a suitable input control (e.g. <select>
      <option value="0">male</option>
      <option value="1">female</option>
    </select> )</p>
    <div class="note">"deprecated" can be used in this way to denote a deprecated option:<br>
    userType = int{"type1"=10, "type2"=10,"old"=0 deprecated}</div>
    <div class="internals note">In the present implementation, this type is called "intEnum" internally.<br>
    Negative numbers are supported (e.g. int { "aa"=5, "bb"=2, "cc"=-10}).</div>
    <h4><a name="real" id="real">real</a></h4>
    <!-- http://bugs.best.eu.org/show_bug.cgi?id=430 --> <!-- http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Double.html -->
    <p>A real number with double precision with (2-2<sup>-52</sup>)&middot;2<sup>1023</sup> as max value and 2<sup>-1074</sup>
    as min value. For example:</p>
    <pre class="example">high= real; high of a person</pre>
    <h4><a name="char">char</a></h4>
    <p>A char field contains a number of characters. Maximal width must be specified and is limited to 255. <span
      class="futfeat">(Optionally a minimal number of characters (lesser than max) can be indicated).</span> Both must
    be positive integers. For example:</p>
    <pre class="example">
#<i>fieldName</i>= char[<i>maxWidth</i>]<br>name= unique char[80]; Username
<span class="futfeat">password= encrypted char[6..10]; Secret password</span>
</pre>
    <p>"<code>unique</code>" and "<code>encrypted</code>" are <a href="#FieldAttributes">field attributes</a>,
    explained below.</p>
    <div class="note">Pay close attention to the character set (charset) for encoding the characters. In Java the
    charset is Unicode, but the JSP/HTML pages have their own encoding settings, as well as the database, etc.</div>
    <p><b>DEPRECATED (use int{...} instead):</b> If the char can have a limited number of value, it can be described
    as follows</p>
    <pre class="example">gender= char{ "male", "female" }; Sex<br></pre>
    <p>This will help the presentation layer to present a suitable input control (e.g. a HTML SELECT)</p>
    <div class="internals note">in the present implementation, this type is called "charEnum" internally</div>
    
    <h4><a name="real" id="boolean">boolean</a></h4>
    <p>A boolean, that can take as values true or false. For example:</p>
    <pre class="example">hasChildren= true; whether this person has children</pre>
    
    
    <h4><a name="text">text</a></h4>
    <p>An unlimited-length string of characters. This type is designed to accommodate large text content. It is implemented with LONGTEXT or its
    counterparts, depending on the underlying DB engine. The text data-type is ready for accepting data in UTF-8 encoding.</p>
    <pre class="example">application= text ; Application letter<br>description=text  ; Description of object</pre>

    <h4><a name="binary">binary</a></h4>
    <p>An unlimited-length field designed for binary content. In contrast to the <code>text</code> data type, binary will always be of 8 bit
    length. It is implemented with LONGTEXT or its counterparts, depending on the underlying DB engine. This type is meant for storing only raw binary
    data, for storing files along with meta-data like a file name, content type, etc., you should rather use the <a href="#file">file data type</a>.</p>
    <pre class="example">singature= binary    ; a binary digital signature</pre>
    
    <h4><a name="date">date</a></h4>
    <p>A date and/or time.</p>
    <pre class="example">birthdate= date; Date of birth<br>arrivalTime= date; Arrival time<br></pre> <!-- FIXME. (fred, 2003-10-13) bug 606

     Should there be a warning about "time".

     Because it really isn't a "time", it would be a "date" where d/m/y fields

     are not set explicitly... but they are filled in with 'random'/'current'

     values. So comparison as "time" < 9am or so is not possible?

 -->
    <h3><a name="StructuralTypes">Structural (relational) types</a></h3>
    <h4><a name="ptr">Pointers (ptr)</a></h4>
    <p>Pointers define a reference to an object of a certain type. For example</p>
    <pre class="example">citizenship= ptr general.Country; Citizenship<br></pre>
    <div class="note futfeat">the <code>ptr</code> keyword might be ommitted in future parsers</div>
    <p>The type can be defined on-the-spot for a single usage. For example</p>
    <pre class="example">addres= ptr ; Address<br>address-&gt;street= char[80]; Street<br>address-&gt;number= int; Number<br></pre>
    <div class="note">The main difference between sets of external types and internal sets is that when the host
    object (e.g. Person.mdd that has the above field "address") is deleted from the database (DB), also all elements of
    the set (addresses) are deleted automatically, so there is no orphans (addresses) in the DB. Elements (addresses) of
    an internal set of some host object (Person X) also can't be used in a set of some other host object (Company Y).</div>

    <!-- FIXME. Is there any relevance to this? bug 607 -->
    <div class="note futfeat">future parsers might read this: <pre class="example">address= ptr{<br>    street= char[80]; Street<br>    number= int; Number}; address<br></pre>
    </div>
    <div class="note internals">this type is known internally as ptrOne</div>

    <h4><a name="set">Sets (set, bag, list)</a></h4>
    <p>Sets define a number of references to multiple objects of a certain type. For example:</p>
    <pre class="example">language= set general.Language; Spoken languages<br></pre>
    <p>This type accomodates sets, bags and lists. The set and list constraints (sets have to contain only one
    element of a certain value and lists have to be ordered) have to be cared for by the programmer. Lists are easy to
    represent, just having an integer field, for the order.</p>
    <p>The type which the set is made of can be defined on the spot:</p>
    <pre class="example">addresses= set; Addresses<br>  addresses-&gt;street= char[80]; Street<br>  addresses-&gt; number= int; Number<br></pre>
    <div class="note futfeat">the future parser might recognize this form: <pre class="example">addresses: set{<br>    street: char[80]; Street<br>    number: int; Number }; Addresses<br></pre>
    </div>
    <div class="internals note">this type is known internally as setComplex</div>
    <p>The set can contain enumerated int values :</p>
    <pre class="example">place= set int {"home"=1, "away"=0} ; Home or away<br></pre>
    <div class="internals note">this is currently known internally as setintEnum</div>
    <p><b>DEPRECATED:</b> The set can contain enumerated char values :</p>
    <pre class="example">place= set char {"home", "away"} ; Home or away<br></pre>
    <div class="note">It means that place is a set that can take only the "home" and "away" values.</div>
    <div class="note internals">This is currently known internally as setcharEnum</div>

    <h4><a name="file">File</a></h4>
    <p>A file data-type is a kind-of record containing several fields needed when wanting to store files. These fields are:</p>
    <ul>
      <li>content (<a href="#binary">binary</a>): the actual binary data of the file.</li>
      <li>name (<a href="#char">char</a>): the file name.</li>
      <li>originalName (<a href="#char">char</a>): the original file name.</li>
      <li>contentType (<a href="#char">char</a>): the MIME content-type of the file.</li>
      <li>contentLength (<a href="#int">int</a>): the content length in byte.</li>
      <li>imageWidth (<a href="#int">int</a>): (only for images) the image width.</li>
      <li>imageHeight (<a href="#int">int</a>): (only for images) the image height.</li>
    </ul>
    <pre class="example">image= file    ; Picture attachment</pre>
    <p>All fields are automatically set by Makumba, all needed to do is to make a &lt;mak:input&gt; on the field name.</p>
    <p>This type should be used in favour of the <a href="#binary">binary data type</a> when you don't want to store only the raw binary data, but
    also meta-data as in the fields above.</p>

    <h3><a name="MacroTypes">Macro types</a></h3>
    <p>A name can be defined for a more complex type and it can be reused in the file. This can be done with a !type
    directive</p>
    <pre class="example">!type.yesno= int{"yes"=1, "no"=0}<br>!type.rank= int{"neutral"=0, "very good"=5, "very bad"=-5}<br>married=yesno<br>happyInLife=rank<br></pre>
    <h3><a name="FieldAttributes">Field attributes</a></h3>
    <ul>
      <li><b>fixed</b> fields can only set during the record's insertion in the database. The subsequent updates
      will not update the field</li>
      <li><b>not null</b> fields will produce a exception if an attempt is made to insert/update without them being
      initialized</li>
      <li><b>unique</b> fields have a unique value in the respective object, for the respective type</li>
      <li class="futfeat"><b>(encrypted</b> fields are encrypted when written to the database and decrypted when
      read)</li>
    </ul>

    <h3><a name="ObjectTitle">Object title</a></h3>
    <div class="note">The object title is used for <i>set</i> and <i>ptr</i> choosers</div>
    <p>One of the fields is always the <i>object title</i>, and is normally presented differently from other fields
    in user interface. For example, when you have a field that is a set and you use a <i>mak:input</i> on that field,
    Makumba will automatically create a list with all the items in the set and it will use the <i>object title</i> to
    know what field to display. The default is the field called "name" if that exists, otherwise it is the first
    non-pointer field in the record description. If another field needs to be title, it can be specified like</p>
    <pre class="example">!title=gender</pre>
    <div class="note">for the on-the spot types in the current implementation, the following notation works: <pre
      class="example">address-&gt;!title= street<br></pre></div>
    <h3><a name="Include">Include mechanism</a></h3>
    <p>A record description can include text from one or more files. This is declared as</p>
    <pre class="example">!include=name_of_included_type<br></pre>
    <p>The included file has the idd extension and is found in a similar way like the data definitions.</p>
    <p>The included file is inserted instead of the !include line. There can be more include lines in a record
    description file. If a field is defined that exists also in the included metadata, the defined field takes
    precedence. If</p>
    <pre class="example">fieldname=<br></pre>
    <p>it means that it does not actually exist. this can be used to cancel an included field.</p>
    <div class="note futfeat">include might be replaced by more advanced concepts such as inheritance and type
    inclusion (rather than reference in foreign table)</div>

    <h2><a name="validation">Validation Rules</a></h2>
    <p>Validation rules are defined inside a data definition, and allow Makumba to automatically validated form data
    input.</p>
    <p>The general syntax of a validation rule definition is as follows:
    <pre class="example">[fieldName or ruleName]%[ruleType] = [validation rule] : [error message]</pre>
    
    <h3>FieldName / ruleName and ruleType</h3>
    <p>For validation rules that operate on one specific field only, you have to use the name of the field; this applies to
    number range, string length and regular-expression rules. For other rules, instead of a field name, you specify the validation
    rule name, which serves an identifier which should be unique. The exact usage of the identifier is not yet specified, but it
    could be used in the future to centralise error messages or provide translations into other languages, etc.</p>
    <p>The <code>ruleType</code> can be one of the following: [range | length | matches | compare | unique]</p>
    
    <h3>Validation rule</h3>
    <p>The validation rule specifies what should be validated, and can be one of the following</p>
    <pre class="example">[range validation | string length | regular expression | comparison | multi-field uniqueness]</pre>
    
    <h4><a name="range">Number range rule</a></h4>
    <p>The range definition rule applies for <code>Number</code> types, i.e. <i>int</i> and <i>real</i>. The
    [validation rule] is defined as:</p>
    <pre class="example">[fieldName]%range = [1..10]</pre>
    <p>Using <code>?</code> allows to keep one parameter unbound, which will default to java.lang.Integer.MIN_VALUE
    and java.lang.Integer.MAX_VALUE, respectively, i.e. +/- 2<sup>31</sup>-1.</p>
    <p>To require that the age needs to be between 12 and 99:</p>
    <pre class="example">age%range = [12..99] : Age must be between 12 and 99!</pre>
    <p>To define that we need to be at least 5 year old, but without any upper limit:</p>
    <pre class="example">age%range = [5..?] : Age must be at least 5!</pre>

    <h4><a name="stringLength">String length rule</a></h4>
    <p>The length definition rule is very similar to the range definition, but applies for <code>string</code> types, i.e. <code>char</code> and <code>text</code>.
    The [validation rule] is defined as:</p>
    <pre class="example">[fieldName]%length = [1..10]</pre>
    <p>Using <code>?</code> allows to keep one parameter unbound, which will default to a minimum length of 0 and a
    maxium length of 255</p>
    <p>To define that the CV needs to be at least 100 characters, define:</p>
    <pre class="example">cv%length = [100..?] : CV must be of decent length!</pre>

    <h4><a name="regexp">Regular expression rule</a></h4>
    <p>The string regular expression rule applies for <code>string</code> types, primarily for <code>char</code>,
    but also for <code>text</code>. The [validation rule] is defined as:</p>
    <pre class="example">[fieldName]%matches = <i>regular expression</i></pre>
    <p>Regular expressions must be valid regular expressions in Java, for more details please refer to the <a
      href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/regex/Pattern.html">specification</a> and <a
      href="http://java.sun.com/docs/books/tutorial/essential/regex/">tutorial</a>.</p>
    <p>To compare if a field contains a valid e-mail address, define:</p>
    <pre class="example">email%matches = .+@.+\.[a-z]+ : Email address is not valid!</pre>

    <h4><a name="comparison">Comparison rule</a></h4>
    <p>This rule allows to compare a field to a constant value or simple function calls.</p>
    <p>The following constants are currently available:</p>
    <table class="tagParamDef">
      <tr>
        <th>Constants</th>
        <th>Description</th>
        <th>Valid</th>
      </tr>
      <tr>
        <td>$now</td>
        <td>The current date and time.</td>
        <td rowspan="2"><code>date</code> types</td>
      </tr>
      <tr>
        <td>$today</td>
        <td>The current date, time set to 00:00.</td>
      </tr>
    </table>
    
    <p>The following functions are currently available:</p>
    <table class="tagParamDef">
      <tr>
        <th>Function</th>
        <th>Description</th>
        <th>Valid</th>
      </tr>
      <tr>
        <td>$date(.., .., .., .., .., ..)</td>
        <td>Constructs a date.<br />
        The function takes up to six arguments, for day, month, year, hours, minutes and seconds. If less than six
        arguments are passed, the missing values will be automatically set to the current date.<br />
        $now is available as a constant for the current date value, and + and - operators can be used to modify that
        value. e.g. <pre class="example">date($now,$now,$now - 5)</pre> evaluates as the current date 5 years
        ago.</td>
        <td><code>date</code> types</td>
      </tr>
      <tr>
        <td>lower(..)</td>
        <td>Converts a string to lower case.</td>
        <td rowspan="2"><code>String</code>, i.e. 'char' and 'text' types</td>
      </tr>
      <tr>
        <td>upper(..)</td>
        <td>Converts a string to upper case.</td>
      </tr>
    </table>
    
    <p>Valid comparison operators are the ones defined in Java:</p>
    <table class="tagParamDef">
      <tr>
        <th>Operator</th>
        <th>Meaning</th>
      </tr>
      <tr>
        <td>==</td>
        <td>equal</td>
      </tr>
      <tr>
        <td>!=</td>
        <td>not equal</td>
      </tr>
      <tr>
        <td>&lt;</td>
        <td>less than</td>
      </tr>
      <tr>
        <td>&gt;</td>
        <td>less than</td>
      </tr>
      <tr>
        <td>=&lt;</td>
        <td>less than or equal</td>
      </tr>
      <tr>
        <td>&gt;=</td>
        <td>greater than or equal</td>
      </tr>
    </table>

    <p>To compare if someone is at least 15 years old, define the following validation rule:</p>
    <pre class="example">minimumAge%compare = birthdate &gt;= date($now,$now,$now - 15) : You have to be at least 15 years old!</pre>

    <p>To ensure that a field doesn't contain only lower-case values, define this rule:</p>
    <pre class="example">nameNotAllLower%compare = lower(name) != name : Your name must not contain only lower-case letters!</pre>

    <p>Two fields can be compared in a similar way</p>
    <pre class="example">graduationCheck%compare = birthdate &lt; graduationDate : You cannot finish school before your birthdate!</pre>

    <h4><a name="multiFielUnique">Multi-field uniqueness definition</a></h4>
    <p>Similar to the <a href="#FieldAttributes"><i>unique</i> field attribute</a>, you can also define multi-field
    uniqueness contraints. These constraints can even span over several data definitions, if they are related via
    pointers.</p>

    <p>Multi-field uniqueness can be defined as follows</p>
    <pre class="example">uniqueAgeEmail%unique = age, email : the combination of age and email must be unique! </pre>
    <br/>

    <div class="note internals">If the fields are in the same data definition, the uniqueness definition will
    translate into a database level multi-field key and uniqueness will be enforced there.<br />
    Otherwise, Makumba will issue a query checking the uniqueness before new or edit operations.</div>

    <h3>Error message</h3>
    <p>The error message that will be displayed if the validation fails.</p>

    </td>
  </tr>
</table>
</div>





<div id="tab_ql" class="content">
<h2><a name="OQL">Query languages</a></h2>
<table width="100%">
  <tr>
    <td valign="top">
    <div class="navbarPage">
    <ul class="navbarPage">
      <li class="section">
        <a href="#MQL">Makumba MQL</a>
        <ul class="navbarPage">
          <li class="sectionLevel2"><a href="#mqlFunctions">functions</a></li>
        </ul>
      </li>
      <li class="section"><a href="#OQL">OQL</a></li>
      <li class="section"><a href="#HQL">Hibernate HQL</a></li>
    </ul>
    </div>
    </td>
    <td>

    <h3 id="MQL">MQL</h3>
    <p>As of Makumba version 0.8.1., the default query language is 'MQL', Makumba Query Language. MQL builds upon <a href="#HQL">Hibernate's
    HQL</a>.</p>

    <h4 id="mqlFunctions">MQL Functions</h4>
    <p>MQL provides support for functions that will translate into SQL functions. Currently, the following functions are supported:</p>
    <h5>String functions</h5>
    <table class="tagParamDef">
      <thead>
        <tr>
          <th>name</th>
          <th>argument(s)</th>
          <th>result type</th>
          <th>description</th>
        </tr>
      </thead>  
      <tbody>
        <tr>
          <td>lower</td>
          <td>(str)</td>
          <td>string</td>
          <td>Converts the string argument to lower case</td>
        </tr>
        <tr>
          <td>upper</td>
          <td>(str)</td>
          <td>string</td>
          <td>Converts the string argument to upper case</td>
        </tr>
        <tr>
          <td>trim</td>
          <td>(str)</td>
          <td>string</td>
          <td>Remove leading trailing spaces.</td>
        </tr>
        <tr>
          <td>ltrim</td>
          <td>(str)</td>
          <td>string</td>
          <td>Remove leading spaces.</td>
        </tr>
        <tr>
          <td>rtrim</td>
          <td>(str)</td>
          <td>string</td>
          <td>Remove trailing spaces.</td>
        </tr>
        <tr>
          <td>concat</td>
          <td>(str1, str2, ...)</td>
          <td>string</td>
          <td>Concatenates two or more strings</td>
        </tr>
        <tr>
          <td>concat_ws</td>
          <td>(separator, str1, str2, ...)</td>
          <td>string</td>
          <td>Concatenates two or more string with the given separator</td>
        </tr>
        <tr>
          <td>substring</td>
          <td>(str, position [, length])</td>
          <td>string</td>
          <td>Takes a substring of the given string</td>
        </tr>
        <tr>
          <td>replace</td>
          <td>(str, fromStr, toStr)</td>
          <td>string</td>
          <td>Replace occurrences of a specified string</td>
        </tr>
        <tr>
          <td>reverse</td>
          <td>(str)</td>
          <td>string</td>
          <td>Returns the string <code>str</code> with the order of the characters reversed. </td>
        </tr>
        <tr>
          <td>ascii</td>
          <td>(str)</td>
          <td>int</td>
          <td>Return numeric value of left-most character.</td>
        </tr>
        <tr>
          <td>character_length</td>
          <td>(str)</td>
          <td>int</td>
          <td>Return number of characters in the string argument.</td>
        </tr>
        <tr>
          <td>format</td>
          <td>(int)</td>
          <td>string</td>
          <td>Return a number formatted to specified number of decimal places</td>
        </tr>
<!--  not yet implemented        
        <tr>
          <td>regexp</td>
          <td><code>expr</code> regexp <code>patt</code></td>
          <td>int (0, 1)</td>
          <td>
            Performs a pattern match of a string expression <code>expr</code> against a pattern <code>patt</code>. For example:
            <pre class="example">SELECT 'makumba!' REGEXP '[a-z]*'; 
 -> 1</pre>
  -->
          </td>
        </tr>        
      </tbody>
    </table>
    
    <h5>Date functions</h5>
    <table class="tagParamDef">
      <thead>
        <tr>
          <th>name</th>
          <th>argument(s)</th>
          <th>result type</th>
          <th>description</th>
        </tr>
      </thead>  
      <tbody>
        <tr>
          <td>dayOfMonth</td>
          <td>(date)</td>
          <td>int</td>
          <td>Return the day of the month (0-31).</td>
        </tr>
        <tr>
          <td>dayOfWeek (alternatively: weekday)</td>
          <td>(date)</td>
          <td>int</td>
          <td>Return the weekday index of the argument.</td>
        </tr>
        <tr>
          <td>week</td>
          <td>(date)</td>
          <td>int</td>
          <td>Return the week number.</td>
        </tr>
        <tr>
          <td>dayOfYear</td>
          <td>(date)</td>
          <td>int</td>
          <td>Return the day of the year (1-366).</td>
        </tr>
        <tr>
          <td>year</td>
          <td>(date)</td>
          <td>int</td>
          <td>Return the year from the date argument.</td>
        </tr>
        <tr>
          <td>month</td>
          <td>(date)</td>
          <td>int</td>
          <td>Return the month from the date argument.</td>
        </tr>
        <tr>
          <td>hour</td>
          <td>(date)</td>
          <td>int</td>
          <td>Return the hour from the date argument.</td>
        </tr>
        <tr>
          <td>minute</td>
          <td>(date)</td>
          <td>int</td>
          <td>Return the minute from the date argument.</td>
        </tr>
        <tr>
          <td>second</td>
          <td>(date)</td>
          <td>int</td>
          <td>Return the second from the date argument.</td>
        </tr>
        <tr>
          <td>extract</td>
          <td>(<code>unit</code> FROM <code>date</code>)</td>
          <td>int</td>
          <td>
            Extracts parts from the date. For example:
            <pre class="example">SELECT EXTRACT(YEAR_MONTH FROM '2009-07-02 01:02:03');
 -> 200907</pre>
            See the <a href="http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html#function_date-add">MySQL Documentation</a> for available units.
          </td>
        </tr>
        <tr>
          <td>monthName</td>
          <td>(date)</td>
          <td>string</td>
          <td>Return the name of the month.</td>
        </tr>
        <tr>
          <td>dayName</td>
          <td>(date)</td>
          <td>string</td>
          <td>Return the name of the day.</td>
        </tr>
        <tr>
          <td>date_add</td>
          <td>(date, INTERVAL <code>expr</code> <code>unit</code>)</td>
          <td>date</td>
          <td>
            Adds <code>expr</code> times the <code>unit</code> to the date. For example:
              <pre class="example">SELECT '2008-12-31 23:59:59' + INTERVAL 1 SECOND;
 -> '2009-01-01 00:00:00'</pre>
              See the <a href="http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html#function_date-add">MySQL Documentation</a> for available units.
            </td>
        </tr>
        <tr>
          <td>date_sub</td>
          <td>(date, INTERVAL <code>expr</code> <code>unit</code>)</td>
          <td>date</td>
          <td>Substracts <code>expr</code> times the <code>unit</code> to the date. See <code>date_add</code>.</td>
        </tr>
        <tr>
          <td>last_day</td>
          <td>(date)</td>
          <td>string</td>
          <td>Return the name of the day.</td>
        </tr>
        <tr>
          <td>current_date</td>
          <td></td>
          <td>date</td>
          <td>Return the current date.</td>
        </tr>
        <tr>
          <td>current_time</td>
          <td></td>
          <td>date</td>
          <td>Return the current time.</td>
        </tr>
        <tr>
          <td>current_timestamp (alternatively: now)</td>
          <td></td>
          <td>date</td>
          <td>Return the current date and time.</td>
        </tr>
      </tbody>
    </table>
    
    <br/>
    <div class="note">Support for new functions is normally easy to add, so if you miss specific functions, please just mail the makumba developers!</div>

    <h3 id="OQL">OQL</h3>
    <p>Before Makumba version 0.8.1, the default query language was OQL. OQL is similar to SQL, a specification can be found at <a
      href="http://www.odmg.org">http://www.odmg.org</a> (or check this <a href="oql-manual.pdf">PDF</a>). Makumba recognized a subset of OQL, which
    it translated to the <a href="SQL-drivers.html">host SQL</a> when necessary. The following language was accepted ([] means optional, {} means any
    number of repetitions):</p>
    <pre class="example"><b>SELECT</b> expression [[<b>AS</b>] label] {, expression [[<b>AS</b>] label] }<br><b>FROM</b> {type [<b>AS</b>] label | label.field{.field} [<b>AS</b>] label }<br>[   <b>WHERE</b> expression<br>    [    <b>GROUP BY</b> expression {,expression}<br>        [  <b>HAVING</b> expression {,expression}  ]<br>    ]<br>]<br>[<b>ORDER BY</b> expression {,expression} [(<b>ASC</b>|<b>DESC</b>)] ]<br></pre>
    <p>Notations like <code>label.field{.field}</code> only allow "<code>field</code>" to be of pointer type in <b><i>expression</i></b>
    and set type in <b>FROM</b>. In expressions, also <code>label.ptr{.ptr}.simplefield</code> is valid.</p>
    <!-- FIXME (fred, 2003-10-14):

     ? add some warning about expressions (e.g. in WHERE or ORDERBY) across

       nullable pointers

       = result is not having the records with null value in the list)

-->
    <p>If a label, representing a type, appears alone in an expression, a default field will be added. The default
    field depends on the type of the label:</p>
    <ul>
      <li>for set XXX types (sets of foreign objects), the label denotes the pointer to the set member</li>
      <li>for set int { } and set char { } types, the label denotes the set member (i.e. and int or a string)</li>
      <li>for all other types, the label denotes the pointer to that object</li>
    </ul>
    <div class="note">In OQL, NULL values are named 'nil', example <pre class="example">ms.account_active=1 OR ms.account_active=nil<br></pre>
    </div>
    <div class="note futfeat">In the future, the MDDs should use 'nil' instead of null, e.g. nickName = not nil
    char[20]</div>

    <h3 id="HQL">Hibernate Query Language - HQL</h3>
    <p>Makumba also integrates <a href="http://www.hibernate.org">Hibernate</a>, thus allowing to take full advantage of hibernate's query
    language HQL. For documentation, please see the <a href="http://www.hibernate.org/89.html">Hibernate Query Language BNF</a>.</p>
    <p>To enable Hibernate in JSP pages, you have to import a different TLD than normally:</p>
    <pre class="example">&lt;%@ taglib uri="http://www.makumba.org/view-hql" prefix="mak" %&gt;<br></pre>
    </div>
    </td>
  </tr>
</table>
</div>





<div id="tab_queryFragments" class="content">
<h2><a name="queryFragments">Query Fragments</a></h2>
<table width="100%">
  <tr>
    <td valign="top">
    <div class="navbarPage">
    <ul class="navbarPage">
      <li class="section"><a href="#mddFunctions">MDD functions</a></li>
      <li class="section"><a href="#funcSpec">Function specification</a></li>
      <li class="section"><a href="#actor">Actor functions</a></li>
      <li class="section"><a href="#explAutho">Explicit authorisation</a></li>
      <li class="section"><a href="#implAutho">Imlicit authorisation</a></li>
      <li class="section"><a href="#queryContext">Query context</a></li>
    </ul>
    </div>
    </td>
    <td>
    <p>Makumba focuses on combining query fragments to obtain high-performance systems with a minimum number of queries sent to the database
    back-end, while keeping its concerns about easy learnability and rapid development. The <a href="makumba-spec.html#tab_list">mak:list engine</a>
    already combines query fragments for embedded mak:lists by combining their FROM and WHERE sections, but we found a need for a better formalization
    and sharing of query fragments across the sytem. The elementary concept of such formalization is the MDD function.</p>
    <h2 id="mddFunctions">MDD Functions</h2>
    <p>A simple function for an MDD called <em>Leveler</em> that has a <em>level </em> integer field looks like</p>
    <pre class="example">
level=int

function(int a) { level+a }</pre>
    <div class="note">In principle, a function is <b>inlined</b> in queries whenever it is encountered in a SELECT projection or WHERE
    condition as follows: <pre class="example">SELECT label.function($param) FROM Leveler label</pre></div>
    <div class="note">The above query is inlined like this: <pre class="example">SELECT label.level + $param FROM Leveler label</pre></div>
    <p>Some properties of MDD functions:</p>
    <ul>
      <li>If the underlying query language allows it, functions can use subqueries.</li>
      <li>If functions wish to refer to the owner object, functions can use <code>this</code> which will be inlined with the label or the
      expression denoting the object in the query</li>
      <li>If a function is not using MDD fields at all, then it is <code>static</code> and can be invoked like <code>MDDname.function(params</code>)</li>
      <li>If functions wish to define labels, they can use a FROM section and if needed a WHERE section to constrain the labels defined.</li>
    </ul>
    
    <div class="internals">In principle it is possible to translate the functions into database-level stored procedures or equivalent but a lot
    can be achieved already just by inlining the functions.</div>
    <p>The main uses of MDD functions are:</p>
    <ul>
      <li>reuse of query code</li>
      <li>query simplification and improved lisibility</li>
      <li>authentication using well-known function names</li>
      <li>authorisation using well-known function names</li>
      <li>data view using well-known function names</li>
    </ul>

    <h2><a name="moreAbtFunctions" id="funcSpec"></a>Function specification</h2>
    <p>The complete specification of function definition is as follows: </p>
<pre class="example">
[sessionVar%]function([type parameter]*){ expression [FROM supplementaryLabels [WHERE condition]]} [errorMessage] [; comment]</pre>
    <ul>
      <li><em>sessionVar </em><a href="http://bugs.best.eu.org/cgi-bin/bugzilla/show_bug.cgi?id=1052">may be used</a> for MDDs that define actors
      (or those related to them) to indicate the name of a session variable where the function result will be stored. This is only possible for
      functions with no parameters. (this is currently implemented but may be deprecated)</li>
      <li>parameter <em>type</em> can be either the primitive types (int, char, date, text, binary, boolean) or an MDD name</li>
      <li><em>expression </em>is a query language expression and may use MDD field names, this, function parameter names, supplementary labels
      (see below), other functions calls, actor invocations and $attributes from the query context
      <ul>
        <li>Since functions are inlined, recursive calls are not possible
        <div class="futfeat">(this is not yet checked though)</div>
        </li>
        <li>$attributes are discouraged because using them would mean counting on &quot;global variables&quot;, it is advised that they are
        passed as function parameters (in case of e.g. page parameters or page/request attributes), or that actor invocations are used to retrieve
        session attributes</li>
      </ul>
      </li>
      <li><em>supplementaryLabels </em>may need to be defined, in which case a normal query language FROM section is used</li>
      <li>sometimes <em>conditions</em> are needed to join the <em>supplementary labels </em>with this.
      <ul>
        <li>supplementaryLabels and WHERE conditions are currently <a href="http://bugs.best.eu.org/cgi-bin/bugzilla/show_bug.cgi?id=1053">not
        implemented</a></li>
      </ul>
      </li>
      <li>if the function is boolean and returns false, an <em>error message</em> will be needed to construct an exception e.g. when an actor()
      function fails (UnauthenticatedException) or when a canRead() function fails (UnauthorizedException). If that functions calls other functions,
      their error messages <a href="http://bugs.best.eu.org/cgi-bin/bugzilla/show_bug.cgi?id=1064">might be composed</a> to provide a more accurate
      reason for failure.</li>
    </ul>
    <div class="note internals">Currently <a href="http://bugs.best.eu.org/cgi-bin/bugzilla/show_bug.cgi?id=1063">two functions with the same name
    are not accepted</a>.</div>
    <div class="note internals">A <a href="http://bugs.best.eu.org/cgi-bin/bugzilla/show_bug.cgi?id=1056">static keyword may be added</a> to function
    definitions.</div>
    <div class="note internals">A <a href="http://bugs.best.eu.org/cgi-bin/bugzilla/show_bug.cgi?id=1056">return type may be added</a> to function
    definitions.</div>


    <h2 id="actor">actor(MDDname) invocations and actor() functions</h2>
    <p>Actors are a special type of function that, when mentioned in queries or functions, may trigger authentication. An <em>actor invocation</em> looks like</p>
    <pre class="example">actor(MDDName)</pre>
    <p>and a query invoking it may be</p>
    <pre class="example">SELECT actor(Person).name 
SELECT obj.hasDoneJob(actor(Person)) FROM SomeType obj</pre>
    <p>These queries are inlined as follows:</p>
    <pre class="example">SELECT actor_Person.name FROM Person actor_Person WHERE actor_Person=$actor_Person
SELECT obj.hasDoneJob($actor_Person) FROM SomeType obj </pre>
    <p>(in the second example, the function <em>hasDoneJob() </em>will be inlined further)</p>
    <p> <em>$actor_Person</em> is a special attribute retrieved from the query context.  The query context handler  will check for the attribute and if it is not defined, it will look in the MDD indicated by the actor attribute name (<em>Person</em>) for <em>actor functions</em>. Assuming that Person has a username and a passoword field, some actor functions may look like</p>
    <pre class="example">username=char[255]
password=char[255]
actor(char[] user){username=user }
actor1(char[] admin){ username=admin }
actor2(char[] user, char []pass){ username=user AND password=pass }</pre>
    <p>First, the context handler will look for a suitable function to use. For example if the attribute <em>user</em> is defined in the context,
    the first function (<em>actor()</em>) will match. However if both the attributes<em> user </em>and <em>pass</em> are defined in the context, the <em>actor2()
    </em>function will match (so the function with most matching parameters will be chosen). Finally, if the <em>admin</em> attribute is found, the <em>actor1()</em>
    function will match.</p>
    <p>The  functions above correspond to different authentication mechanisms that may be used. The first two functions use an external authentication mechanism, where  the <em>role</em> of a correctly authenticated user is provided. In such a case, the Makumba query context handler will define an attribute with th role as name (<em>user</em>, <em>admin</em>) and the username as value. The third function (<em>actor2()</em>) will be useful when authentication is managed by the web application (for example using the <a href="http://www.makumba.org/makumba-spec.html#Login">mak:login</a> feature) and the authentication data is passed as request parameter, in this case they are expected to be called <em>user</em> and <em>pass.</em></p>
    <p>Once a function has been selected (say <em>actor2()</em>) the following query is ran:</p>
    <pre class="example">SELECT x FROM Person x WHERE x.actor($user, $pass)</pre>
    <p>which inlines to</p>
    <pre class="example">SELECT x FROM Person x WHERE x.username=$user AND x.password=$pass   
</pre>
    <p>Once the actor is authenticated, the <em>$actor_Person</em> attribute is put in the session part of the query context. It can be removed
    using <em>&lt;<a href="http://www.makumba.org/makumba-spec.html#Login">mak:logout</a> actor=&quot;Person&quot; /&gt; </em>. Some fields of Person
    (the MDD declaring the actor) <a href="http://bugs.best.eu.org/cgi-bin/bugzilla/show_bug.cgi?id=1052">may also be put in the session</a>, along
    with the results of functions with no parameters, and along with related objects.</p>


    <h2 id="explAutho">Explicit authorisation constraints</h2>
    <p>Explicit authorisation constraints are associations between web application paths and query language expressions. When an access is made to
    a resource whose path matches an authorisation constraint (partial matches supported, longest match considered), the corresponding expression is
    evaluated. If the expression produces an error (like UnauthenticatedException), that will be handled. If the exception returns 0, false or null an
    UnauthorizedException is raised with an error message indicated in the constraint.</p>
    <p>Currently explicit authorisation constraints can be put in the file MakumbaController.properties. authorisation constraints  looks like: </p>
<pre class="example">authorize%/={actor(Person)}
authorize%/admin=(char[]admin){actor(Person).username=admin} You are not an administrator </pre>
    <p>The first example makes the whole site accessible to users who can authenticate as a Person actor.</p>
    <p>The second example makes the /admin part of the site accesible only if there   is an admin attribute in the context, and if that is the username of the Person actor. If any constraint fails, an UnauthorizedException will be raised. The second example also shows how to indicate a specific message for the exception, which will then be displayed to the user.</p>

    <h2 id="implAutho" class="futfeat">Implicit authorisation constraints (not yet implemented) </h2>
    <p>Implicit authorisation constraints are defined in functions like canRead(), canInsert(), canUpdate(), canDelete() in the respective MDDs.
    These functions will be used whenever a <a href="http://www.makumba.org/makumba-spec.html#tab_list">mak:list</a>, <a
      href="http://www.makumba.org/makumba-spec.html#makobject">mak:object</a> or <a href="http://www.makumba.org/makumba-spec.html#makobject">mak:*Form</a>
    attempts to view, create, change or delete an obect of the respective type. The following features are intended:</p>
    <ul>
      <li>
      <div class="futfeat"><a href="http://bugs.best.eu.org/cgi-bin/bugzilla/show_bug.cgi?id=1059">filter out</a> from mak:list and mak:object
      objects that the user is not authorized to see, but do not raise any exception if there are such objects.This will probably be the default for <a
        href="http://www.makumba.org/makumba-spec.html#tab_list">mak:list</a></div>
      </li>
      <li>
      <div class="futfeat"><a href="http://bugs.best.eu.org/cgi-bin/bugzilla/show_bug.cgi?id=1061">block access</a> to the whole page if the
      user is not authorized. This will probably be the default for <a href="http://www.makumba.org/makumba-spec.html#makobject">mak:object</a>, and <a
        href="http://www.makumba.org/makumba-spec.html#makobject">mak:*Form</a></div>
      </li>
      <li>
      <div class="futfeat"><a href="http://bugs.best.eu.org/cgi-bin/bugzilla/show_bug.cgi?id=1060">not link</a> to a page that is not authorized</div>
      </li>
    </ul>

    <h2 id="queryContext">Query execution context</h2>
    <p>A query execution context is a set of known attributes. In the case of JSP this concept maps on the page, request, and session attributes, as well as request parameters. If however application logic is executed before launching a JSP, the context will be made of the session and request attributes and of request parameters. This is managed by two different <em>query context handlers </em>(implementing the interface Attrributes)  and other such handlers can be defined.  </p>
    <p>Actor functions define a special type of session attributes that are computed based on other attributes from the query context.</p>

    </td>
  </tr>
</table>
</div>



<div id="tab_intro" class="content">
<h2><a name="Presentation">Presentation with JSP taglib</a></h2>
<table width="100%">
  <tr>
    <td valign="top">
    <div class="navbarPage">
    <ul class="navbarPage">
      <li class="section"><a href="#controller">Makumba Controller</a></li>
      <li class="section"><a href="#tagparameters">JSP tag parameters</a></li>
      <li><a href="#response">&lt;mak:response/&gt;</a></li>
    </ul>
    </div>
    </td>
    <td>Data can be presented and edited per record and field. The current presentation language uses JSP taglibs
    and corresponding notation, but principles can be applied in any other HTML-centric presentation language such as
    PHP.
    <h3><a name="JspIntro">Makumba in Java Server Pages</a></h3>
    Makumba offers a JSP custom tag library, that allows easy interaction (viewing, editing) with the data in your
    database, right from your HTML (actually, JSP) document. Since Makumba pages, are essentially JSP pages, a basic
    understanding of JSP will be helpful to make more advanced use of makumba. Same goes for knowing a bit of Java
    itself. But you can get a long way with just a few notions! Really.
    <p>Makumba tags are written according to <a href="http://java.sun.com/products/servlet/">Servlet 2.3
    specification</a> and <a href="http://java.sun.com/products/jsp/">JSP 1.1 specification</a>. You will need a so-called
    "servlet container" that supports them both, such as <a href="http://jakarta.apache.org/tomcat/">Apache Tomcat</a>.
    The corresponding <b>WEB-INF/makumba.tld</b> is already included in the <a href="download.html">distribution</a> <code>makumba.jar</code>.
    The example <b>WEB-INF/web.xml</b> can be found in Makumba <a
      href="http://cvs.sourceforge.net/viewcvs.py/*checkout*/makumba/makumba/servlet_context/WEB-INF/">cvs
    repository</a>.</p>
    <p>Before using Makumba tags in your JSP pages you also need to declare the taglib with:</p>
    <pre class="example">&lt;%@ taglib uri="http://www.makumba.org/presentation" prefix="mak" %&gt;<br></pre>
    <p>A few resources on JSPs (don't be afraid to try first, read later) :</p>
    <ul>
      <li><a href="http://java.sun.com/products/jsp/docs.html">JSP documentation by Sun</a></li>
      <li><a href="http://java.sun.com/webservices/tutorial.html">J2EE web services documentation by Sun</a>. This
      is an introduction on the various technologies that you might use when building webapplications using Java2
      (J2EE).</li>
      <li><a href="http://www.apl.jhu.edu/%7Ehall/java/Servlet-Tutorial/Servlet-Tutorial-JSP.html">Gentle
      introduction to JSPs</a></li>
    </ul>
    <h4><a name="controller">Makumba Controller</a></h4>
    <p>The makumba controller is a component running in the 'servlet container'. When a request for a makumba page
    enters the servlet container, the controller will intercept the request, and perform its "controller" activities
    (cfr. the model-view-controller pattern) :</p>
    <ul>
      <li>checking if the page has the appropriate attributes (see handler initialisation; e.g. force login).</li>
      <li>checking if the page request is the result of a form submit or a deleteLink. If so, perform the relevant
      actions in the handler and database.</li>
      <li>deal with problems (exceptions) during the controller activity:
      <ul>
        <li>if <a href="api/org/makumba/LogicException.html"><code>org.makumba.LogicException</code></a> is thrown,
        the Exception can write a message to the <a href="#response"><code>&lt;mak:response&gt;</code></a> in the
        requested page.</li>
        <li><a href="api/org/makumba/UnauthenticatedException.html"><code>org.makumba.UnauthenticatedException</code></a>
        and <a href="api/org/makumba/UnauthorizedException.html"><code>org.makumba.UnauthorizedException</code></a> will
        force login <span class="futfeat">(although UnauthorizedException probably shouldn't, <a
          href="http://bugzilla.makumba.org/show_bug.cgi?id=444">bug 444</a>)</span></li>
        <li>if another exception occurs, an errorPage will be shown instead of the requested page.</li>
      </ul>
      </li>
    </ul>
    <p>For this to work, the correct configuration must be applied in <code>WEB-INF/web.xml</code> (<a
      href="http://cvs.sourceforge.net/viewcvs.py/*checkout*/makumba/makumba/servlet_context/WEB-INF/">example file</a>).
    The following would tell the makumba controller to filter all requests for .jsp files.</p>
    <pre class="example">  &lt;filter&gt;<br>     &lt;filter-name&gt;makumba_controller&lt;/filter-name&gt;<br>     &lt;filter-class&gt;org.makumba.controller.http.ControllerFilter&lt;/filter-class&gt;<br>  &lt;/filter&gt;<br><br>  &lt;filter-mapping&gt;<br>    &lt;filter-name&gt;makumba_controller&lt;/filter-name&gt;<br>    &lt;url-pattern&gt;*.jsp&lt;/url-pattern&gt;<br>  &lt;/filter-mapping&gt;<br></pre>
    <p>Note that if (in this example) the result page for a makumba form would be an <code>.html</code> page, then
    the makumba controller would not intercept the <code>.html</code> page request, and the actions implied by the form,
    would not be performed.</p>
    <h4><a name="tagparameters">JSP tag parameters</a></h4>
    <p>JSP-tag parameter values are either <b>FIXED</b> or <b>RTEXPR</b> (runtime expression). A <b>FIXED</b> tag
    parameter must have a constant, literal value, while an <b>RTEXPR</b> can also be of the form &lt;%= java_expression
    %&gt;. On the other hand, <i>some</i> FIXED parameters can contain jsp attributes like $attr in makumba tags.</p>
    <p>All parameters are <b>optional</b> unless specifically mentioned as being <b>mandatory</b>.</p>
    <p>Specific concern can be the <b>parameter quoting</b>. Tag parameters can be written as name="value" or
    name='value' (note: the stringLiteral on DATE must be quoted with "). The choice of quote can be determined by the
    need to use either double or single quote as part of the value itself. If the quote is also present within the
    value, it must be escaped by a backslash.</p>
    <pre class="example">  &lt;mak:list from="general.Person p" where="p.gender=\"male\"" &gt;<br>  &lt;mak:list from="general.Person p" where='p.gender="male"' &gt;<br>  &lt;mak:list from="general.Person p" where="p.gender='male'" &gt;<br>  &lt;mak:list from="library.Book b" where="b.publisher=\"O'Reilly\" " &gt;    <!-- FIXME (fred) I'm not 100% sure this is correct --><br>  &lt;mak:list from="library.Book b" where='b.publisher="O\'Reilly" ' &gt;<br></pre>
    <p>Quotes in <b>extra HTML formatting</b> parameters, such as <code>styleClass</code>, <code>title</code>, <code>styleId</code>,
    <code>onClick</code> ... need some special attention with quotes. The parameter values are copied verbatim (with no
    modifications by makumba) to the resulting HTML, always surrounded with double quotes ("). This means that you have
    to use other quotes, like single one ('),<br>
    If you need to pass a literal <b>backslash</b> (\) you have to escape it with a preceeding backslash (\\).</p>
    <pre class="example">  &lt;mak:input ... onClick="alert(this.value);"/&gt;<br>  &lt;mak:input ... onClick="alert('Hello world!');"/&gt;<br>  &lt;mak:input ... onClick="alert('Hello\\nWorld');"/&gt;<br></pre>
    <p>Unfortunately the idea to use a sequence of escapes, eg writing \\\' in the JSP page to set the tag attribute
    to \', which could be handy for javascript tag attributes, is confusing the Tomcat servlet container.</p>


    <!-- ========================================================= --> 
    <!-- ====================== mak:response ===================== -->
    <h3><a name="response">&lt;mak:response/&gt;</a></h3>
    <p><code>&lt;mak:response/&gt;</code> prints information about the results of the actions that were performed by
    the <a href="#controller">makumba controller</a> (e.g. for a form submit or deleteLink): It either displays the <code>message="..."</code>
    parameter of the form tag (in green) in case of success, or (in red) the message of a uncaught <code>LogicException</code>
    resulting from Business Logic. Other exception types will provoke an exception page. <!-- Fred: not true:

<p>Absence of the &lt;mak:response/> tag on a page that is the response to a form, will result in an run-time error.

--></p>The message is wrapped into a HTML SPAN tag which is member of 2 classes:
      <ul>
        <li>makumbaResponder for all responses</li>
        <li>makumbaError for erroneous responses</li>
        <li>makumbaSuccess for successful responses</li>
      </ul>
    This allows you to add css-styles accordingly. To do this, you must <strong>set the option useDefaultResponseStyles to false</strong> in
    Makumba.conf! Otherwise the span will have the color set in the style attribute of the span (see examples).   
    <p>
    <p><em>Examples:</em>
      <table>
        <tr>
          <th>Situation</th><th>mak:response output</th>
        </tr>
        <tr>
          <td>Successful response,<br/>default configuration</td>
          <td><pre class="example">&lt;span class="makumbaResponder makumbaSuccess" style="color:green"&gt;Message&lt;/span&gt;</pre></td>
        </tr>
        <tr>
          <td>Logic exception thrown,<br/>default configuration</td>
          <td><pre class="example">&lt;span class="makumbaResponder makumbaError" style="color:red"&gt;ErrorMessage&lt;/span&gt;</pre></td>
        </tr>
        <tr>
          <td>Successful response,<br/>useDefaultResponseStyles=false</td>
          <td><pre class="example">&lt;span class="makumbaResponder makumbaSuccess"&gt;Message&lt;/span&gt;</pre></td>
        </tr>
        <tr>
          <td>Logic exception thrown,<br/>useDefaultResponseStyles=false</td>
          <td><pre class="example">&lt;span class="makumbaResponder makumbaError"&gt;ErrorMessage&lt;/span&gt;</pre></td>
        </tr>      </table>
    </p>
    </p>
    <p>The unformatted message is available as request-scope attribute <code>makumba.response</code>, the formatted message as
     <code>makumba.responseFormatted</code>. The jsp page can get hold of the message using e.g.</p>
    <pre class="example">&lt;% String s = (String) request.getAttribute("makumba.response") %&gt;<br></pre>
    <p>Similarly, request-scope attribute <code>makumba.successfulResponse</code> is set <i>only</i> in case of
    successful action execution.</p>
    <pre class="example">&lt;% if (null == request.getAttribute("makumba.successfulResponse")) { /* action failed */ } %&gt;<br></pre>
    <p class="futfeat">(A body-tag style (<code>&lt;mak:response&gt;...&lt;/mak:response&gt;</code>) will be added
    later, to display different messages for different circumstances (errors). It will also be possible to get hold of
    the actual exception object. )</p>

    </td>
  </tr>
</table>
</div>





<div id="tab_list" class="content">
<h2><a name="Presentation">JSP taglib - listing</a></h2>
<table width="100%">
  <tr>
    <td valign="top">
    <div class="navbarPage">
    <ul class="navbarPage">
      <li class="section"><a href="#makobject">&lt;mak:object&gt;</a></li>
      <li class="section"><a href="#usageOFAttributes">Attributes and OQL in &lt;mak:list&gt; and
      &lt;mak:object&gt;</a></li>
      <li class="section"><a href="#makvalue">&lt;mak:value/&gt;</a></li>
      <li class="section"><a href="#makcount">mak:count(), mak:maxCount(), mak:lastCount()</a></li>
      <li class="section"><a href="#pagination">&lt;mak:pagination&gt;</a></li>
      <li class="section"><a href="#makif">&lt;mak:if&gt;</a></li>
      <li class="section"><a href="#mak_attrib">&lt;mak:attribute&gt;</a></li>
    </ul>
    </div>
    </td>
    <td>
    <h3><a name="maklist">&lt;mak:list...&gt;...&lt;/mak:list&gt;</a></h3>
    <p>Performs a query on the database. The body of the list, if present, is run once for every item in the
    resulting data (size 0..N), e.g. to display it. Queries are generated on the spot and can be nested.</p>
    <p>Example:</p>
    <pre class="example">&lt;mak:list from="best.Student s, s.person p" where="p.gender=\"male\""<br>          orderBy="p.name"&gt;<br><br>    &lt;c:if test="${mak:count()==1}"&gt;<br>       &lt;p&gt; There are ${mak:maxCount()} male students:<br>    &lt;/c:if&gt;<br><br>    &lt;br&gt; &lt;%= counter %&gt;.<br>    &lt;mak:value expr="p.name"/&gt;<br>    &lt;mak:value expr="p.surname"/&gt; &lt;br&gt;<br>    &lt;mak:list from="p.addresses a"&gt;<br>       &lt;mak:value expr="a.streetno"/&gt; &lt;mak:value expr="a.city"/&gt;<br>    &lt;/mak:list&gt;<br>&lt;/mak:list&gt;<br><br>&lt;c:if test="${mak:lastCount()==0}"&gt; There are no male students. &lt;/c:if&gt;<br></pre>
    <p></p>
    <table class="tagParamDef">
      <thead>
        <tr>
          <th>tag parameter</th>
          <th>description</th>
          <th>comments</th>
        </tr>
      </thead>  
      <tbody>
        <tr>
          <td><tt>db</tt></td>
          <td>The makumba database to connect to. The format is <code><i>Host_SQLEngineType_DatabaseName</i></code>
          <br>
          If not present, the default database is used. See <a href="SQL-drivers.html">database configuration and
          lookup</a>.</td>
          <td>Fixed, cannot contain attributes, for now. <br>
          The default database is chosen if this argument is not set. <br>
          Can only be set for top-level (root) query tags<br>
          Can be a Rtexpr &lt;%= ...%&gt;</td>
        </tr>
        <tr>
          <td><tt>from</tt></td>
          <td><a href="#OQL">OQL FROM</a> section. If the query is nested, the keys from the parent's query are
          added to this FROM section in the resulting query</td>
          <td>Fixed, Mandatory.</td>
        </tr>
        <tr>
          <td><tt>variableFrom</tt></td>
          <td>supplementary, variable <a href="#OQL">OQL FROM</a> section.</td>
          <td>Fixed, can contain #{ JSP EL expressions }</td>
        </tr>
        <tr>
          <td><tt>where</tt></td>
          <td><a href="#OQL">OQL WHERE</a> section. If the query is nested, the WHERE section from the parent's
          query, is added to this in the resulting query</td>
          <td>Fixed, can contain #{ JSP EL expressions }</td>
        </tr>
        <tr>
          <td><tt>groupBy</tt></td>
          <td><a href="#OQL">OQL GROUP BY</a>&nbsp; section</td>
          <td>Fixed, can contain #{ JSP EL expressions }</td>
        </tr>
        <tr>
          <td><tt><span class="futfeat">(having)</span></tt></td>
          <td><span class="futfeat"><a href="#OQL">OQL HAVING</a>&nbsp; section</span></td>
          <td><span class="futfeat">Fixed</span></td>
        </tr>
        <tr>
          <td><tt>orderBy</tt></td>
          <td><a href="#OQL">OQL ORDER BY</a>&nbsp; section</td>
          <td>Fixed, can contain #{ JSP EL expressions } <tt class="oldfeat">label.$fieldname used to be
          supported, not anymore</tt></td>
        </tr>
        <tr>
          <td style="vertical-align: top;"><tt>offset</tt></td>
          <td style="vertical-align: top;">the offset of the result to show (0 for starting from the first result)<br>
          </td>
          <td style="vertical-align: top;">Fixed ($attribute allowed). If $attribute is not found, defaults to 0. Only allowed for the outermost mak:list<br>
          </td>
        </tr>
        <tr>
          <td style="vertical-align: top;"><tt>limit</tt></td>
          <td style="vertical-align: top;">the maximum numbers of results to show (-1 for all results)<br>
          </td>
          <td style="vertical-align: top;">Fixed ($attribute allowed). Only allowed for the outermost mak:list. if $attribute is not found, defaults to the value of <code>defaultLimit</code>, if present, or -1 otherwise.<br>
          <span class="futfeat">LIMIT can limit the query time dramatically, but the children mak:lists are not
          yet limited.</span><br>
          </td>
        </tr>
        <tr>
          <td style="vertical-align: top;"><tt>defaultLimit</tt></td>
          <td style="vertical-align: top;">the default value for limit, if the $attribute in limit="$attribute" is not present.</td>
          <td style="vertical-align: top;">Fixed ($attribute allowed). Only allowed for the outermost mak:list.<br>
        </tr>
        <tr>
          <td><tt class="oldfeat">countVar</tt></td>
          <td><span class="oldfeat">The <code>java.lang.Integer</code> variable that will contain the number
          of the current iteration.</span></td>
          <td><span class="oldfeat">Fixed. A new Java variable is created, so no other variable by the same
          name can exist in the Java scope at that point in the JSP. Deprecated, use mak:count() expression language
          function instead</span></td>
        </tr>
        <tr>
          <td><tt class="oldfeat">maxCountVar</tt></td>
          <td><span class="oldfeat">The <code>java.lang.Integer</code> variable that will contain the total
          number of iterations.</span></td>
          <td><span class="oldfeat">Fixed. A new Java variable is created, so no other variable by the same
          name can exist in the Java scope at that point in the JSP. Deprecated, use mak:maxCount() expression language
          function instead</span></td>
        </tr>
        <tr>
          <td><tt class="oldfeat">separator</tt></td>
          <td><span class="oldfeat">Character string as separator between two list elements. It is not
          included before the first or after the last</span><span class="oldfeat"></span></td>
          <td><span class="oldfeat">D</span><span class="oldfeat"></span><span class="oldfeat">eprecated,
          use &lt;c:if test="${mak:count&lt;mak:maxCount()}"&gt; instead</span>.</td>
        </tr>
        <tr>
          <td><tt>id</tt></td>
          <td>Tag's identifier</td>
          <td>Fixed. Can be used to distinguish otherwise identical tags on a page (to avoid confusion by Makumba's
          JSP analyser)</td>
        </tr>
      </tbody>
    </table>
    <h4><a name="makobject">&lt;mak:object&nbsp; ...&gt;.... &lt;/mak:object&gt;</a></h4>
    <p>Like list, but the query can only have zero or one result. A zero value for <code>maxCountVar</code> and <code>countVar</code>
    indicate that the object does not exist.</p>
    <p>Example: See <a href="#maklist"><code>&lt;mak:list&gt;</code></a>.</p>
    <!-- FIXME; fred: "this needs to be rewritten, assuming no knowledge of the concept of jsp attributes,

                   thus with an intro on the subject. Explaining the diff between Java scope and Attribute scope." -->
    <h4><a name="usageOFAttributes">Attributes and OQL</a> in &lt;mak:list &gt; and &lt;mak:object &gt;</h4>
    <p>Attributes are accessible through <code>$AttributeName</code> to any makumba tag. Typically they will be
    present in OQL sections instead of <code>$number</code> attributes (therefore the OQL sections of these tags is not
    "pure"). For example:</p>
    <pre class="example">&lt;mak:list from="best.internal.Lbg"<br>          where="lbg.country=$country"<br>          orderBy="lbg.$lbg_order"&gt;<br>  .....<br>&lt;/mak:list&gt;<br></pre>
    <p>If a <code>$</code> (dollar) sign needs to be in the string, the escape is <code>$$</code>. <br>
    If at the end of an attribute there has to be a Java identifier letter, the attribute name can be written as <code>text1$attrName$text2</code>,
    that is, with <code>$</code> at both ends.</p>
    <p>The http parameters are automatically set as page attributes. Other attributes can be set by the Java code as
    attributes in any scope (page, request, session, application) using <code><a
      title="external link, servlet API" href="http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/jsp/PageContext.html">pageContext.setAttribute(name,
    value, scope)</a></code>.</p>
    <p>The query generator is setting all the attributes that are logically possible as prepared query parameters.
    For example, the $country above is a query parameter since it's a value, but the $lbg_order will not be accepted as
    query parameter, since it's a field name.</p>
    <p>If an attribute has multiple values, it is expanded into multiple OQL parameters. For example:</p>
    <pre class="example">&lt;mak:list from="best.internal.Lbg" where="lbg.status in set($status)" &gt;<br></pre>
    <p></p>
    <div class="futfeat">(For view-level attributes such as lbg_order above, the value range can be defined by : <br>
    &nbsp;&nbsp;&nbsp;<code>&lt;mak:defineAttribute name="lbg_order" values="name, id" default="name"/&gt;</code> )
    <p>(Later: Maybe the page might want to set attributes. Something like : <br>
    &nbsp;&nbsp;&nbsp;<code>&lt;mak:setAttr name="lbg" from="best.internal.Lbg lbg" where ... scope="session"
    /&gt;</code> <br>
    Then the attribute could be used as <code>$lbg</code> in the rest of the page/session/application... Con: such stuff
    is normally done by the Java code. )</p>
    </div>
    <h4><a name="makvalue">&lt;mak:value&nbsp; .../&gt;</a></h4>
    <p>Displays the value of an expression from within the query.</p>
    <p>Example:</p>
    <pre class="example">&lt;mak:list from="best.Student s, s.person p"<br> where="p.gender=\"male\"" orderBy="p.name"&gt;<br>    &lt;mak:value expr="p.name"/&gt;<br>    &lt;mak:value expr="p.surname"/&gt;<br>    &lt;mak:value expr="p.birthdate" var="birth" printVar="printBirth"/&gt;<br>    &lt;% // we only print the birthdate if it's after some date<br>         if ( ((java.util.Date)birth).after(new java.util.Date(1980, 0, 1)) )<br>             out.print(printBirth);<br>    %&gt;<br>    &lt;mak:value expr="s.person.favoriteQuote" maxLength="60" addTitle="auto" /&gt;<br>&lt;/mak:list&gt;</pre>
    <br>
    <p></p>
    <table class="tagParamDef">
      <tbody>
        <tr>
          <th>tag parameter</th>
          <th>description</th>
          <th>comments</th>
        </tr>
        <tr>
          <td><tt>expr</tt></td>
          <td><a href="#OQL">OQL SELECT</a> projection expression. It will be displayed if <code>var</code> nor <code>printVar</code>
          are not specified.</td>
          <td>Fixed, Mandatory.</td>
        </tr>
        <tr>
          <td><tt>var</tt></td>
          <td>The value of the expression is set to a new <code>java.lang.Object</code> variable by this name, as
          well as to a page-scope attribute, also by the same name (accessible as <code>$attributename</code>).</td>
          <td>Fixed. A new Java variable is created, so no other variable by the same name can exist in the Java
          scope at that point in the JSP. <br>
          Note: the Java variable must be cast to its specific type (Integer, String, Date, Text, <a href="api/org/makumba/Pointer.html">Pointer</a>, Vector)
          before using it as such.</td>
        </tr>
        <tr>
          <td><tt>printVar</tt></td>
          <td>The formatted output as it would have been printed, is instead stored in a new <code>java.lang.String</code>
          variable by this name, as well as to a page-scope attribute by the same name (accessible as <code>$attributename</code>).
          </td>
          <td>Fixed. A new Java variable is created, so no other variable by the same name can exist in the Java
          scope at that point in the JSP.</td>
        </tr>
        <tr>
          <td><tt>urlEncode</tt></td>
          <td>Indicates if the expression will be part of an URL or not. If "true", the output is URL-encoded.
          Default is "false".</td>
          <td>Rtexpr.</td>
        </tr>
        <tr>
          <td><tt>html</tt></td>
          <td>Normal behaviour is to transform character output to its HTML escaped form. If this is "<code>true</code>",
          content is assumed to be HTML, and is not escaped. If "<code>auto</code>", heuristically checks the content
          for HTML tags and inhibits escape if there are any. Default is "<code>false</code>".</td>
          <td>Rtexpr. Only char[] and text</td>
        </tr>
        <tr>
          <td><tt>format</tt></td>
          <td>Format string to specify the formatting of a date value, according to <code><a
            title="external link, servlet API"
            href="http://java.sun.com/j2se/1.4.2/docs/api/java/text/SimpleDateFormat.html">java.text.SimpleDateFormat</a></code>
          </td>
          <td>Rtexpr. Only for date. Defaults to "<code>dd MMMM yyyy</code>"</td>
        </tr>
        <tr>
          <td><tt>lineSeparator</tt></td>
          <td>Separator for long lines. If a text consists of short lines only, it will be surrounded by <code>&lt;pre&gt;...&lt;/pre&gt;</code>.
          Default is "<code>&lt;p&gt;</code>".</td>
          <td>Rtexpr. Only for text. Current implementation is <a
            href="http://bugzilla.makumba.org/show_bug.cgi?id=38">buggy</a>: separator is added before every long line,
          instead of between every long line.</td>
        </tr>
        <tr>
          <td><tt>longLineLength</tt></td>
          <td>The length of a long line. If a text contains long lines, it will be printed differently. See <code>lineSeparator</code>.
          Default is "30"</td>
          <td>Rtexpr. Only for text.</td>
        </tr>
        <tr>
          <td><tt>maxLength</tt></td>
          <td>The maximum length (number of characters) to print. Longer output is cut off, and an <code>ellipsis</code>
          is added to indicate the cut. If not set (default), there is no maximum.</td>
          <td>Rtexpr. Only applies for char[] AND if it is not already HTML formatted (cfr. <code>html</code>).</td>
        </tr>
        <tr>
          <td><tt>ellipsis</tt></td>
          <td>The character string to print to indicate that the text extended the <code>maxLength</code>. Default
          is "...". The final printed string, including the <code>ellipsis</code>, will not exceed <code>maxLength</code>.</td>
          <td>Rtexpr</td>
        </tr>
        <tr>
          <td><tt>ellipsisLength</tt></td>
          <td>The equivalent character length of <code>ellipsis</code>. By default, this is the number of
          characters in <code>ellipsis</code>. But if <code>ellipsis</code> is e.g. HTML code, then that is not
          appropriate.</td>
          <td>Rtexpr. <br>
          <u>Example</u>, the ellipsis is an image of approx 3 characters wide. <code>ellipsis="&lt;img
          src=icon.gif width=10 height=10&gt;" ellipsisLength="3"</code></td>
        </tr>
        <tr>
          <td><tt>addTitle</tt></td>
          <td>If "<code>true</code>", add an HTML tooltip with the value, to the printed output. If "<code>auto</code>",
          add tooltip only if the printed output is cut (cfr <code>maxLength</code>). Default is "<code>false</code>". <br>
          </td>
          <td>Rtexpr. Note: implementated by producing as output: <code>&lt;span title="<i>printVar</i>"&gt;<i>possibly-cut-printVar</i>&lt;/span&gt;</code>
          </td>
        </tr>
        <tr>
          <td><tt>default</tt></td>
          <td>The character string to print if the <code>expr</code> results in a NULL value. Default is <code>default=""</code>
          (i.e. zero-length string)<br>
          Support not available for: date, "choice" = ptr, set, setCharEnum<!-- bug 501--></td>
          <td>Rtexpr</td>
        </tr>
        <tr>
          <td><tt>empty</tt></td>
          <td>The character string to print if the normal printed output would be empty (i.e. zero-length string).
          Therefore, this is also used for case <code>expr=NULL</code> and <code>default=""</code>.</td>
          <td>Rtexpr<br>
          </td>
        </tr>
      </tbody>
    </table>
    <h4><a name="makcount">mak:count(), mak:maxCount(), mak:lastCount()</a></h4>
    These are JSP EL (expression language) functions that give information about the iterations in a list.
    <ul>
      <li>mak:count() gives the number of the current iteration inside a mak:list or mak:object. It has no value
      outside that tag.</li>
      <li>mak:maxCount() gives the total number of iterations inside a mak:list or mak:object (1). It has no value
      outside that tag.</li>
      <li>mak:lastCount() gives the total number of iterations of the previous mak:list or mak:object,
      respectively. It has no value inside the mak:list/object.
      <div class="note">Note: if you want to store the value of some mak:list/object for usage in/after a later
      mak:list/object, you can do that with &lt;c:set var="<i>someVariableName</i>" value="${mak:lastCount()}" just
      after that mak:list/object.</div>
      </li>
    </ul>
    Example using the Java Standard Tag Library (<a href="http://java.sun.com/products/jsp/jstl/">JSTL</a>, prefix "c"):
    <br>
    <pre class="example">&lt;mak:list ...&gt;<br>   &lt;c:if test="${mak:count()==1}"&gt;These are the list elements: &lt;/c:if&gt;<br>   &lt;tr bgcolor="${mak:count()%2==1?"white":"grey"}"&gt;<br>       &lt;td&gt;this shows in alternative colors&lt;/td&gt;<br>   ...<br>   &lt;c:if test="${mak:count()!=mak:maxCount()}"&gt;<br>       a separator where we can have any &lt;b&gt;tag&lt;/b&gt; <br>       we don't want separators to be shown after the last element <br>   &lt;/c:if&gt;<br>&lt;/mak:list&gt;<br>&lt;c:if test="${mak:lastCount()==0}"&gt;These are no elements &lt;/c:if&gt;<br></pre>

    <!-- ========================================================= --> 
    <!-- ====================== mak:if =========================== -->
    <h4><a name="makif">&lt;mak:if&nbsp; ...&gt; ... &lt;/mak:if&gt;</a></h4>
    <p>Displays the body of the tag only if the OQL expression evaluates to true.</p>
    <p>Example :</p>
    <pre class="example">&lt;mak:list from="best.Student s"<br>   where="s.person.birthdate &lt;&gt; nil" orderBy="s.name"&gt;<br>   &lt;mak:value expr="s.person.name"/&gt;<br>   &lt;mak:if test="s.person.hideAge = 0"&gt;<br>      was born on &lt;mak:value expr="s.person.birthdate" /&gt;<br>   &lt;/mak:if&gt;<br>&lt;/mak:list&gt;<br></pre>
    <br>
    <p></p>
    <table class="tagParamDef">
      <tbody>
        <tr>
          <th>tag parameter</th>
          <th>description</th>
          <th>comments</th>
        </tr>
        <tr>
          <td><tt>test</tt></td>
          <td>
          <p><a href="#OQL">OQL SELECT</a>&nbsp; projection expression. It must be a test, resulting in a 'boolean'
          in SQL : 0 or 1.</p>
          <p>for the test expressions: =, !=, &lt;, &lt;=, &gt;, &gt;=</p>
          </td>
          <td>Fixed, Mandatory. <br>
          <i>(in first implementation, this was called <code>expr</code>, but changed to reflect practice in XSL and
          <a href="http://java.sun.com/products/jsp/jstl/" title="JSP Standard Tag Library">JSTL</a>)</i></td>
        </tr>
      </tbody>
    </table>

    <!-- ========================================================= --> 
    <!-- ====================== mak:pagination =================== -->
    <h4><a name="pagination">&lt;mak:pagination&nbsp; .../&gt;</a></h4>
    <p>Provides pagination of the results in an enclosing &lt;mak:list&gt;. The tag provides links to the first, previous, next and last item in
    the result set, and the page number currently displayed.<br />
    To achieve this, pagination makes use of the information provided by the enclosing &lt;mak:list&gt;, i.e. the offset and limit, and automatically
    computes the total of rows that would be returned by the list, if no limit was specified.</p>
    <p>Example:</p>
    <pre class="example">
&lt;mak:list from="best.Student s" offset="$offset" limit="$limit" defaultLimit="25" orderBy="s.name"&gt;
  &lt;mak:pagination action="studentList.jsp" title="true" itemName="Students" /&gt;
  &lt;mak:value expr="s.person.name"/&gt;, born on &lt;mak:value expr="s.person.birthdate" /&gt;
  &lt;mak:pagination action="studentList.jsp" title="true" itemName="Students" /&gt;
&lt;/mak:list&gt;
</pre>
    <br>
    <p></p>
    <table class="tagParamDef">
      <tbody>
        <tr>
          <th>tag parameter</th>
          <th>description</th>
          <th>comments</th>
        </tr>
        <tr>
          <td><tt>action</tt></td>
          <td>The target page to go to when clicking on a pagination link.</td>
          <td>Rtexpr.</td>
        </tr>
        <tr>
          <td><tt>itemName</tt></td>
          <td>The name of the items displayed, to be used in the text "Showing 'itemName' x out of y (Page z)".</td>
          <td>Rtexpr.</td>
        </tr>
        <tr>
          <td><tt>paginationLinkTitle</tt></td>
          <td>Whether or not to display title="..." elements on the pagination links.</td>
          <td>Fixed; defaults to <code>true</code></td>
        </tr>
        <tr>
          <td><tt>styleClass</tt></td>
          <td rowspan="14" colspan="2">Generic html tag attribute, see <a href="#maknew"><code>newForm</code></a></td>
        </tr>
      </tbody>
    </table>
    <h4><a name="mak_attrib">&lt;mak:attribute&nbsp; .../&gt;</a></h4>
    <!-- when bug 64 is fixed uncomment this:

<b>DEPRECATED</b>, use <a href="#makvalue">&lt;mak:value></a> instead, like:

<pre class="example">

&lt;mak:value expr="$pattern" ... />

</pre>

<p>

-->
    <p>Displays the value of an attribute, or sets it to a Java variable.</p>
    <p>Example:</p>
    <pre class="example">&lt;mak:attribute name="pattern" var="pattern" exceptionVar="exception"/&gt;<br><br>&lt;% if (exception!=null) {<br>     pageContext.setAttribute("pattern", (String)pattern+"%");<br>%&gt;<br>   &lt;mak:list from="type t" where="t.field like $pattern" &gt;...&lt;/mak:list&gt;<br><br>&lt;% } else { %&gt;<br>   No pattern argument. Please indicate one.<br>&lt;% } %&gt;<br></pre>
    <br>
    <p></p>
    <table class="tagParamDef">
      <tbody>
        <tr>
          <th>tag parameter</th>
          <th>description</th>
          <th>comments</th>
        </tr>
        <tr>
          <td><tt>name</tt></td>
          <td>the name of the attribute. Will be printed if <tt>var </tt>is not present and there is no exception
          when finding the argument. If there is an exception but <tt>exceptionVar</tt> is indicated, nothing will be
          printed.</td>
          <td>Fixed, Mandatory.</td>
        </tr>
        <tr>
          <td><tt>var</tt></td>
          <td>The name of the <code>java.lang.Object</code> variable where to store the attribute value. Note that
          you will have to cast it to its specific type.</td>
          <td>Fixed</td>
        </tr>
        <tr>
          <td><tt>exceptionVar</tt></td>
          <td>The name of the created <code>java.lang.Throwable</code> variable that will hold eventual exceptions
          raised when trying to compute the attribute. If <code>exceptionVar</code> is missing, any raised exception
          will stop page execution. If it is present, and <code>AttibuteNotFoundException</code> occurs, the attribute
          is set to <code>null</code> (so a next request for the attribute will return <code>null</code>)</td>
          <td>Fixed</td>
        </tr>
        <tr>
          <td><tt>db</tt></td>
          <td>The database in which the business logic (if any) will compute the attribute. The default database is
          normally used.</td>
          <td>Fixed</td>
        </tr>
      </tbody>
    </table>


    </td>
  </tr>
</table>
</div>




<div id="tab_forms" class="content">
<h2><a name="Presentation">JSP taglib - Forms</a></h2>
<table width="100%">
  <tr>
    <td valign="top">
    <div class="navbarPage">
    <ul class="navbarPage">
      <li class="section"><a href="#maknew">&lt;mak:newForm&gt;</a></li>
      <li class="section"><a href="#makadd">&lt;mak:addForm&gt;</a></li>
      <li class="section"><a href="#makedit">&lt;mak:editForm&gt;</a></li>
      <li class="section"><a href="#makform">&lt;mak:form&gt;</a></li>
      <li class="section"><a href="#input">&lt;mak:input&gt;</a> and <a href="#choiceDisplay">&lt;mak:option&gt;</a></li>
      <li class="section"><a href="#action">&lt;mak:action&gt;</a></li>
      <li><a href="#delete">&lt;mak:delete/&gt;</a></li>
    </ul>
    </div>
    </td>
    <td>

    <p>Makumba can produce four types of forms: new, add, edit and generic forms.</p>
    <p>All forms have a number of common features: They can include <code>&lt;mak:input &gt;</code> tags. They all
    can have "<code>action</code>", "<code>method</code>", "<code>handler</code>", "<code>name</code>" and "<code>message</code>"
    arguments.</p>
    <p>Handler methods (if they exist) are executed by the <a href="#controller">makumba controller</a>, when the
    form is submitted to another makumba page.</p>
    <p><b>Non-generic (type specific) forms</b> <br>
    New, edit and add forms are type specific. Their fields must be named after the fields in the respective type (and
    related fields).</p>
    <p>If there is a <a href="#Business">business logic class</a>, the engine will look (once after each page
    compilation) for the corresponding <b>handler method</b>. The handler methods are executed before the default action
    and may prevent the action from being executed by throwing an exception. Some forms also have an after-action
    handler method.</p>
    <p>If the handler class exists but no handler method can be found, an error is thrown (the site is not allowed
    to do the operation, e.g. StudentHandler will never have a on_newLibraryBook() method). If the handler class wishes
    to allow the action, it can define an empty handler method.</p>
    <p><strong>Multiple forms</strong><!-- http://bugs.best.eu.org/show_bug.cgi?id=37 --> <br>
    - addForms can add to the subsets of object produced by the enclosing newForm.<br>
    - any number of levels of form inclusion is possible but only the outermost form can have an action, onSubmit, and
    method and other attributes specific to HTML forms.<br>
    - all form actions take place in a single transaction, which is rolled back by the controller filter if there is an
    error. <br>
    - after_ methods are not executed in correct order (<a href="http://bugs.best.eu.org/show_bug.cgi?id=689">bug
    689</a>)</p>
    <pre class="example">&lt;mak:form action="blabla"&gt;<br>&lt;%-- the topmost form, will result in a HTML form, may or may not have logic, <br>     or it can be a specialized form (new, edit, add...)<br>--%&gt;<br><br>  &lt;mak:input name="first" /&gt; &lt;%-- the topmost form can have fields of its own --%&gt;<br><br>&lt;mak:list .... &gt; <br>&nbsp; &lt;mak:addForm object="bla" field="bla" &gt;<br>  &lt;%-- note that there is no action indicated here, it's the action of the <br>       topmost form a normal on_add BL method will be called <br>   --%&gt;<br>&nbsp;&nbsp;   &lt;mak:input name="second" /&gt;&lt;%-- the topmost form can have fields of its own, <br>                                     even repeated in loops <br>                                --%&gt;<br>     ...<br>  &lt;/mak:addForm&gt;<br>&lt;/mak:list&gt;<br><br>&lt;mak:list .... &gt; &lt;%-- there can be more than one loop in a root form -- %&gt;<br>...<br>&lt;/mak:list&gt;<br>&lt;input type=submit&gt; &lt;%-- it's easy to add a submit button anywhere --%&gt;<br>&lt;/mak:form&gt;<!-- bug: the after_ BL method should be invoked after the subform responders : http://bugs.best.eu.org/show_bug.cgi?id=689 --></pre>
    <p class="futfeat">(Later, new and edit forms that have no body, will build default forms. )</p>

    <p id="formAnnotation"><strong>Form annotation</strong> <br />
    Form validation errors are either reported in the <a href="#response">Makumba response</a> which would be displayed on the form action
    page, or can for improved usability be annotated in the form itself. In the latter case, on a form validation error, the form page itself would be
    displayed again, and errors are displayed next to the inputs that failed validation.<br/>
    An example can be seen below:

    <div class="renderExample">
      <table>
        <tr>
          <td>age</td>
          <td><input name="age" value="1r" maxlength="10" id="age" type="text"> &nbsp; <span style="color: red; font-weight: bold">invalid integer: 1r</span></td>
        </tr>
        <tr>
          <td>weight</td>
          <td><input name="weight" value="24b" maxlength="10" id="weight" type="text"> &nbsp; <span style="color: red; font-weight: bold">invalid real: 24b</span></td>
        </tr>
      </table>
    </div>

    <p>The annotation message will be put inside a <code>&lt;span class="formAnnotation"&gt;</code>; this CSS-class can be used to add custom
    formatting to the message.</p>

    <p>Reloading the form page on errors can be triggered by the attribute <code>reloadFormOnError</code>, the location of the annotation message
    by the attribute <code>annotation</code>.</p>
    <p>Additionally, form validation can be done also on the client-side, i.e. in the browser. Client-side validation can be either live, i.e. on
    entering data in an input, or before form submission; this is controlled by the attribute <code>clientSideValidation</code>.</p>

    <h4><a name="maknew">&lt;mak:newForm&nbsp; ...&gt;.... &lt;/mak:newForm&gt;</a></h4>
    <p>Makes a form for creating a new object of the indicated type. <!-- FIXME (fred 2003-10-18) should include description of

 how also related object can be created at the same time



   ptr.externalpointer (needs be fixed, notnull, ... ????)

   ptr.internalpointer ????



--></p>
    <p>Example (personNew.jsp):</p>
    <pre class="example">&lt;mak:newForm type="general.Person" action="personList.jsp" method="post"&gt;<br>        &lt;mak:input name="name"/&gt;<br>        &lt;mak:input name="surname"/&gt;<br>        &lt;input type="submit"&gt;<br>&lt;/mak:newForm&gt;<br></pre>

    <p id="multiFormSubmission"><strong>Multiple submission of forms</strong><!-- http://bugs.best.eu.org/show_bug.cgi?id=37 --> <br>
    
    <p>If new forms are submitted more than once (intentionally or by accident, e.g. impatient users pressing twice one a submit button, reloading
    a form result page, ...), problems might occur in the data integrity.<br>
    Makumba has a built-int mechanism to prevent multiple submission of forms; a ticket will be generated on form load, containing a form-specific key
    and a time stamp. Each ticket is only valid for a single form submission. Upon subsequent submission of the very same form, an error message will
    be displayed.</p>
    <div class="note">Note that this does not prevent duplicate entries, it just prevents double submission of one specific form instance. To
    prevent duplicate entries, define unique keys.</div>

    <br/>
    <table class="tagParamDef">
      <tbody>
        <tr>
          <th>tag parameter</th>
          <th>description</th>
          <th>comments</th>
        </tr>
        <tr>
          <td><tt>type</tt></td>
          <td>Makumba type for record creation, or OQL label for subrecord creation</td>
          <td>Fixed, mandatory.</td>
        </tr>
        <tr>
          <td><tt><span class="futfeat">(handler)</span></tt></td>
          <td><span class="futfeat">the Java class.method that handles the response</span></td>
          <td>defaults to on_new+NameOfMakumbaType. Arguments: <br>
          (<a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/Dictionary.html">Dictionary</a> newData,&nbsp; <a href="api/org/makumba/Attributes.html">Attributes</a> a, <a href="api/org/makumba/Transaction.html">Transaction</a> db)</td>
        </tr>
        <tr>
          <td><tt>action</tt></td>
          <td>the response page of the form</td>
          <td>Mandatory if a <a href="#action">&lt;mak:action&gt;</a> is absent</td>
        </tr>
        <tr>
          <td><tt>method</tt></td>
          <td>the HTTP method (<code>get</code> or <code>post</code>)</td>
          <td>Defaults to <code>get</code></td>
        </tr>
        <tr>
          <td><tt>name</tt></td>
          <td>the name of the created object in the response page</td>
          <td>Fixed. Defaults to __mak__edited__. If set, it is also used for the name of the html form (<code>&lt;form
          name="..." ...&gt;</code>)</td>
        </tr>
        <tr>
          <td><tt>message</tt></td>
          <td>the message that is displayed in the response page upon success</td>
          <td>Fixed. Defaults to "changes done".</td>
        </tr>
        <tr>
          <td><tt>multipleSubmitErrorMsg</tt></td>
          <td>Enables <a href="#multiFormSubmission">multiple form submission prevention</a>, and sets the given value as the error message.</td>
          <td>Rtexpr.</td>
        </tr>
        <tr>
          <td><tt>reloadFormOnError</tt></td>
          <td>Indicates whether the form page shall be reloaded on an error, or the specified form action page will be loaded</td>
          <td>Fixed. Values are <code>true</code> or <code>false</code>; defaults to <code>false</code>.</td>
        </tr>
        <tr>
          <td><tt>annotation</tt></td>
          <td>Indicates that validation whether errors should be shown in the form, or be displayed in the <code>&lt;mak:response/&gt;</code>.</td>
          <td>Taken into account only if <code>reloadFormOnError</code> is not set to <code>false</code>.<br>
          Values are <code>none</code> (displayed in <code>&lt;mak:response/&gt;</code>), <code>before</code> (before the input), <code>after</code> (after the input) or <code>both</code> (displayed both before and after the input).
          Defaults to <code>none</code>.
        </tr>
        <tr>
          <td><tt>annotationSeparator</tt></td>
          <td>Fixed. Prints the given separator between the annotation and the input field.</td>
          <td>Also HTML can be used, e.g. printing an error icon.</td>
        </tr>
        <tr>
          <td><tt>clientSideValidation</tt></td>
          <td>Controls whether client side validation shall be used.</td>
          <td>Rtexpr. Values are <code>false</code> (off), <code>true</code> (on submission) or <code>live</code> (while tpying).</td>
        </tr>
        <!--form specific:-->
        <tr>
          <td><tt>target</tt></td>
          <td rowspan="3">Form-specific html tag attributes</td>
          <td rowspan="3">The content is copied to the resulting <code>&lt;form...&gt;</code> tag. Careful with
          (escaping) <a href="#tagparameters">quotes</a>.</td>
        </tr>
        <tr>
          <td><tt>onReset</tt></td>
        </tr>
        <tr>
          <td><tt>onSubmit</tt></td>
        </tr>
        <!-- generic: -->
        <tr>
          <td><tt>styleId</tt></td>
          <td rowspan="14">Generic HTML tag attributes.</td>
          <td>results in <code>id="..."</code></td>
        </tr>
        <tr>
          <td><tt>styleClass</tt></td>
          <td>results in <code>class="..."</code></td>
        </tr>
        <tr>
          <td><tt>style</tt></td>
          <td rowspan="12">The content is copied to the resulting html tags. Careful with (escaping) <a
            href="#tagparameters">quotes</a>.</td>
        </tr>
        <tr>
          <td><tt>title</tt></td>
        </tr>
        <tr>
          <td><tt>onClick</tt></td>
        </tr>
        <tr>
          <td><tt>onDblClick</tt></td>
        </tr>
        <tr>
          <td><tt>onKeyDown</tt></td>
        </tr>
        <tr>
          <td><tt>onKeyUp</tt></td>
        </tr>
        <tr>
          <td><tt>onKeyPress</tt></td>
        </tr>
        <tr>
          <td><tt>onMouseDown</tt></td>
        </tr>
        <tr>
          <td><tt>onMouseUp</tt></td>
        </tr>
        <tr>
          <td><tt>onMouseMove</tt></td>
        </tr>
        <tr>
          <td><tt>onMouseOut</tt></td>
        </tr>
        <tr>
          <td><tt>onMouseOver</tt></td>
        </tr>
      </tbody>
    </table>
    <p><a name="handler_methods"></a>At form response, makumba (controller) invokes the following methods:</p>
    <ol>
      <li>
      <p>By defining <code>on_new*</code>, the handler class gets the opportunity to validate/change the data. If
      the data is not correct, the handler can throw an exception to prevent insertion in database.</p>
      <pre class="example">handler.<b>on_new<i>TypeName</i>(data, attr, db)</b>;<br></pre></li>
      <li>
      <p>The standard Database call for insertion:</p>
      <pre class="example">Pointer created= <a
        href="api/org/makumba/Database.html#insert%28java.lang.String,%20java.util.Dictionary%29">db.insert(type, data)</a>;<br></pre>
      </li>
      <li>
      <p>By defining <tt>after_new*</tt>, the handler class gets the opportunity to do supplementary operations with
      the inserted record.</p>
      <pre class="example">handler.<b>after_new<i>TypeName</i>(created, data, attr, db)</b>;<br></pre></li>
    </ol>
    <br>
    <table class="tagParamDef">
      <tbody>
        <tr>
          <th>argument</th>
          <th>Java type</th>
          <th>comments</th>
        </tr>
        <tr>
          <td><code>data</code></td>
          <td><code><a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/Dictionary.html">java.util.Dictionary</a></code></td>
          <td>The new record to create. It is read from the HTTP query string by interpreting the form.</td>
        </tr>
        <tr>
          <td><code>attr</code></td>
          <td><a href="api/org/makumba/Attributes.html"><code>org.makumba.Attributes</code></a></td>
          <td>Other attributes in the page (sent as HTTP arguments or present in the HTTP session).</td>
        </tr>
        <tr>
          <td><code>db</code></td>
          <td><a href="api/org/makumba/Transaction.html"><code>org.makumba.Transaction</code></a></td>
          <td>The database where the record will be inserted</td>
        </tr>
        <tr>
          <td><code>created</code></td>
          <td><a href="api/org/makumba/Pointer.html"><code>org.makumba.Pointer</code></a></td>
          <td>The pointer to the created record. Only for <code>after_new</code></td>
        </tr>
      </tbody>
    </table>
    <p>If the handler class is present but both handler methods are missing (<code>on_new</code> and <code>after_new</code>),
    the action is not allowed.</p>
    <p>At response the following calls are executed (in this order):</p>
    <pre class="example">PersonLogic handler_obj; // see <a href="#javahand">handler discovery</a><br>handler_obj.<b>checkAttributes(attr, db)</b>;<br>handler_obj.<b>on_newGeneralPerson(data, attr, db)</b>;<br><a href="api/org/makumba/Pointer.html">Pointer</a> created= db.insert("general.Person", data);<br>handler_obj.<b>after_newGeneralPerson(created, data, attr, db)</b>;<br></pre>
    <h4><a name="makadd">&lt;mak:addForm&nbsp; ...&gt;.... &lt;/mak:addForm&gt;</a></h4>
    <p>Makes a form for creating a sub-object of the mandatory enclosing <code>&lt;mak:object&gt;</code> (e.g. a
    language of a student, an address for a person).</p>
    <p>Example:</p>
    <pre class="example">&lt;mak:object from="best.Student s" where="s=$student"&gt;<br>    &lt;mak:addForm object="s" field="languages"<br>         action="studentView.jsp" method="post"&gt;<br>        &lt;mak:value expr="s.name"/&gt;<br>        &lt;mak:input name="level"/&gt;<br>        &lt;mak:input name="comments"/&gt;<br>    &lt;/mak:addForm&gt;<br>&lt;/mak:object&gt;<br></pre>
    <br>
    <p></p>
    <table class="tagParamDef">
      <tbody>
        <tr>
          <th>tag parameter</th>
          <th>description</th>
          <th>comments</th>
        </tr>
        <tr>
          <td><tt>object</tt></td>
          <td>The label of the object whose sub-object will be created</td>
          <td>Fixed, mandatory</td>
        </tr>
        <tr>
          <td><tt>field</tt></td>
          <td>The field name that denotes the sub-object.</td>
          <td>Fixed, mandatory.</td>
        </tr>
        <tr>
          <td class="futfeat"><tt>(handler)</tt></td>
          <td class="futfeat">the Java class.method that handles the response</td>
          <td>defaults to <code>on_add+MakumbaType+fieldname</code>. Arguments: <code>(<a href="api/org/makumba/Pointer.html">Pointer</a> baseObject,
          <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/Dictionary.html">Dictionary</a> newData,&nbsp; <a href="api/org/makumba/Attributes.html">Attributes</a> a, <a href="api/org/makumba/Transaction.html">Transaction</a> db)</code></td>
        </tr>
        <!-- 

  <tr> 

    <td>multiple</td>

    <td>true ???</td>

    <td>II didn't find this in makumba taglib but it's in the changelog

  <br>http://bugs.best.eu.org/show_bug.cgi?id=37</td>

  </tr>

  -->
        <tr>
          <td><tt>action</tt></td>
          <td colspan="2" rowspan="7">see <a href="#maknew"><code>newForm</code></a></td>
        </tr>
        <tr>
          <td><tt>method</tt></td>
        </tr>
        <tr>
          <td><tt>name</tt></td>
        </tr>
        <tr>
          <td><tt>message</tt></td>
        </tr>
        <tr>
          <td><tt>reloadFormOnError</tt></td>
        </tr>
        <tr>
          <td><tt>annotation</tt></td>
        </tr>
        <tr>
          <td><tt>annotationSeparator</tt></td>
        </tr>
        <!--form specific:-->
        <tr>
          <td><tt>target</tt></td>
          <td rowspan="3" colspan="2">Form-specific html tag attributes, see <a href="#maknew"><code>newForm</code></a></td>
        </tr>
        <tr>
          <td><tt>onReset</tt></td>
        </tr>
        <tr>
          <td><tt>onSubmit</tt></td>
        </tr>
        <!-- generic: -->
        <tr>
          <td><tt>styleId</tt></td>
          <td rowspan="14" colspan="2">Generic html tag attributes, see <a href="#maknew"><code>newForm</code></a>
          </td>
        </tr>
        <tr>
          <td><tt>styleClass</tt></td>
        </tr>
        <tr>
          <td><tt>style</tt></td>
        </tr>
        <tr>
          <td><tt>title</tt></td>
        </tr>
        <tr>
          <td><tt>onClick</tt></td>
        </tr>
        <tr>
          <td><tt>onDblClick</tt></td>
        </tr>
        <tr>
          <td><tt>onKeyDown</tt></td>
        </tr>
        <tr>
          <td><tt>onKeyUp</tt></td>
        </tr>
        <tr>
          <td><tt>onKeyPress</tt></td>
        </tr>
        <tr>
          <td><tt>onMouseDown</tt></td>
        </tr>
        <tr>
          <td><tt>onMouseUp</tt></td>
        </tr>
        <tr>
          <td><tt>onMouseMove</tt></td>
        </tr>
        <tr>
          <td><tt>onMouseOut</tt></td>
        </tr>
        <tr>
          <td><tt>onMouseOver</tt></td>
        </tr>
      </tbody>
    </table>
    <p>This will call the handler methods: (the argument names are adapted to the example. Note the changed pointer
    argument in the methods.)</p>
    <pre class="example">on_addBestStudentLang(<a href="api/org/makumba/Pointer.html">Pointer</a> student, <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/Dictionary.html">Dictionary</a> languageData, <a href="api/org/makumba/Attributes.html">Attributes</a> pageParams, <a href="api/org/makumba/Transaction.html">Transaction</a> db)<br>after_addBestStudentLang(<a href="api/org/makumba/Pointer.html">Pointer</a> address, <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/Dictionary.html">Dictionary</a> languageData, <a href="api/org/makumba/Attributes.html">Attributes</a> pageParams, <a href="api/org/makumba/Transaction.html">Transaction</a> db)<br></pre>
    <h4><a name="makedit">&lt;mak:editForm&nbsp; ...&gt;.... &lt;/mak:editForm&gt;</a></h4>
    <p>Makes a form for editing the object indicated by any of the labels of the mandatory enclosing <code>&lt;mak:object&gt;</code>
    or <code>&lt;mak:list&gt;</code>. Also linked objects can be edited through the same form.</p>
    <p>Example:</p>
    <pre class="example">&lt;mak:object from="best.Student s, s.person p" where="s=$student"&gt;<br>    &lt;mak:editForm object="s" action="studentView.jsp" method="post"&gt;<br>        &lt;mak:input name="person.name"/&gt;<br>        &lt;mak:input name="person.surname"/&gt;<br>        &lt;mak:input name="graduated"/&gt;<br>    &lt;/mak:editForm&gt;<br>&lt;/mak:object&gt;<br></pre>
    <br>
    <p></p>
    <table class="tagParamDef">
      <tbody>
        <tr>
          <th>tag parameter</th>
          <th>description</th>
          <th>comments</th>
        </tr>
        <tr>
          <td><tt>object</tt></td>
          <td>The label of the OQL object to edit</td>
          <td>Fixed, mandatory.</td>
        </tr>
        <tr>
          <td class="futfeat"><tt>(handler)</tt></td>
          <td class="futfeat">the Java class.method that handles the response</td>
          <td>defaults to <code>on_edit+MakumbaTypeOfEditedObject</code>. Arguments: <code>(<a href="api/org/makumba/Pointer.html">Pointer</a> object,
          <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/Dictionary.html">Dictionary</a> changedFields, <a href="api/org/makumba/Attributes.html">Attributes</a> a, <a href="api/org/makumba/Transaction.html">Transaction</a> db)</code></td>
        </tr>
        <tr>
          <td><tt>action</tt></td>
          <td colspan="2" rowspan="7">see <a href="#maknew"><code>newForm</code></a></td>
        </tr>
        <tr>
          <td><tt>method</tt></td>
        </tr>
        <tr>
          <td><tt>name</tt></td>
        </tr>
        <tr>
          <td><tt>message</tt></td>
        </tr>
        <tr>
          <td><tt>reloadFormOnError</tt></td>
        </tr>
        <tr>
          <td><tt>annotation</tt></td>
        </tr>
        <tr>
          <td><tt>annotationSeparator</tt></td>
        </tr>
        <!--form specific:-->
        <tr>
          <td><tt>target</tt></td>
          <td rowspan="3" colspan="2">Form-specific html tag attributes, see <a href="#maknew"><code>newForm</code></a></td>
        </tr>
        <tr>
          <td><tt>onReset</tt></td>
        </tr>
        <tr>
          <td><tt>onSubmit</tt></td>
        </tr>
        <!-- generic: -->
        <tr>
          <td><tt>styleId</tt></td>
          <td rowspan="14" colspan="2">Generic html tag attributes, see <a href="#maknew"><code>newForm</code></a>
          </td>
        </tr>
        <tr>
          <td><tt>styleClass</tt></td>
        </tr>
        <tr>
          <td><tt>style</tt></td>
        </tr>
        <tr>
          <td><tt>title</tt></td>
        </tr>
        <tr>
          <td><tt>onClick</tt></td>
        </tr>
        <tr>
          <td><tt>onDblClick</tt></td>
        </tr>
        <tr>
          <td><tt>onKeyDown</tt></td>
        </tr>
        <tr>
          <td><tt>onKeyUp</tt></td>
        </tr>
        <tr>
          <td><tt>onKeyPress</tt></td>
        </tr>
        <tr>
          <td><tt>onMouseDown</tt></td>
        </tr>
        <tr>
          <td><tt>onMouseUp</tt></td>
        </tr>
        <tr>
          <td><tt>onMouseMove</tt></td>
        </tr>
        <tr>
          <td><tt>onMouseOut</tt></td>
        </tr>
        <tr>
          <td><tt>onMouseOver</tt></td>
        </tr>
      </tbody>
    </table>
    <p>The response will call the handler method: (the argument names are adapted to the example)</p>
    <pre class="example">on_editBestStudent(<a href="api/org/makumba/Pointer.html">Pointer</a> student, <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/Dictionary.html">Dictionary</a> fieldsToChange, <a href="api/org/makumba/Attributes.html">Attributes</a> pageParams, <a href="api/org/makumba/Transaction.html">Transaction</a> db)<br></pre>
    <!-- ========================================================= --> 
    <!-- ====================== mak:form ========================= -->
    <h4><a name="makform">&lt;mak:form&nbsp; ...&gt;....&lt;/mak:form&gt;</a></h4>
    <p>Creates a <b>generic form</b>, that may call a handler method in response. It allows the JSP author to make
    any kind of form. They are suitable for more complex operations than new, add, edit.</p>
    <p>Example:</p>
    <pre class="example">&lt;mak:object from="best.Student s" where="s=$student"&gt;<br>    &lt;mak:form handler="doSomething" action="studentView.jsp" method="post"&gt;<br>        &lt;mak:input name="xxx" value="s.person.name"/&gt;<br>        &lt;input type=submit&gt;<br>    &lt;/mak:form&gt;<br>&lt;/mak:object&gt;<br></pre>
    <br>
    <p></p>
    <table class="tagParamDef">
      <tbody>
        <tr>
          <th>tag parameter</th>
          <th>description</th>
          <th>comments</th>
        </tr>
        <tr>
          <td><tt>handler</tt></td>
          <td>the Java method that handles the response</td>
          <td>Arguments: <code>(<a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/Dictionary.html">Dictionary</a> formFields, <a href="api/org/makumba/Attributes.html">Attributes</a> restOfArguments, <a href="api/org/makumba/Transaction.html">Transaction</a> db)</code> <br>
          Not mandatory. A form without handler will simply set attributes (as makumba objects) for the next page</td>
        </tr>
        <tr>
          <td><tt>action</tt></td>
          <td colspan="2" rowspan="7">see <a href="#maknew"><code>newForm</code></a></td>
        </tr>
        <tr>
          <td><tt>method</tt></td>
        </tr>
        <tr>
          <td><tt>name</tt></td>
        </tr>
        <tr>
          <td><tt>message</tt></td>
        </tr>
        <tr>
          <td><tt>reloadFormOnError</tt></td>
        </tr>
        <tr>
          <td><tt>annotation</tt></td>
        </tr>
        <tr>
          <td><tt>annotationSeparator</tt></td>
        </tr>
        <!--form specific:-->
        <tr>
          <td><tt>target</tt></td>
          <td rowspan="3" colspan="2">Form-specific html tag attributes, see <a href="#maknew"><code>newForm</code></a></td>
        </tr>
        <tr>
          <td><tt>onReset</tt></td>
        </tr>
        <tr>
          <td><tt>onSubmit</tt></td>
        </tr>
        <!-- generic: -->
        <tr>
          <td><tt>styleId</tt></td>
          <td rowspan="14" colspan="2">Generic html tag attributes, see <a href="#maknew"><code>newForm</code></a>
          </td>
        </tr>
        <tr>
          <td><tt>styleClass</tt></td>
        </tr>
        <tr>
          <td><tt>style</tt></td>
        </tr>
        <tr>
          <td><tt>title</tt></td>
        </tr>
        <tr>
          <td><tt>onClick</tt></td>
        </tr>
        <tr>
          <td><tt>onDblClick</tt></td>
        </tr>
        <tr>
          <td><tt>onKeyDown</tt></td>
        </tr>
        <tr>
          <td><tt>onKeyUp</tt></td>
        </tr>
        <tr>
          <td><tt>onKeyPress</tt></td>
        </tr>
        <tr>
          <td><tt>onMouseDown</tt></td>
        </tr>
        <tr>
          <td><tt>onMouseUp</tt></td>
        </tr>
        <tr>
          <td><tt>onMouseMove</tt></td>
        </tr>
        <tr>
          <td><tt>onMouseOut</tt></td>
        </tr>
        <tr>
          <td><tt>onMouseOver</tt></td>
        </tr>
      </tbody>
    </table>
    <!-- ========================================================= --> 
    <!-- ====================== mak:input ======================== -->
    <h4><a name="input">&lt;mak:input... /&gt;</a></h4>
    <p>An input field to be created, depending on the makumba type of the field.</p>
    <p><b>Set and pointer</b> inputs will render as <code>select</code> boxes. Sometimes you may need to use two select boxes whereby the
    user can move items from one box to the other, which is illustrated in this <a href="scripts/makumba-JavaScriptChooser.html">example</a>.</p>
    <p><b>Date inputs</b> are slightly different than normal inputs, as they are rendered with several input fields (for the
    day, month, year, hours, minutes and second, depending on the date/time format). Additionally, a JavaScript-based calendar
    widget can be used, as shown in an <a href="scripts/makumba-JavaScriptCalendar.html">example</a>.</p>
    <p>The difference between <code>&lt;mak:input &gt;</code> and normal HTML <code>&lt;input&gt;</code> in a
    makumba form are:</p>
    <ul>
      <li><code>&lt;mak:input&gt;</code> produces objects prepared for setting/comparing makumba fields (e.g.
      <a href="api/org/makumba/Pointer.html">Pointer</a>, Date, Text).</li>
      <li>the fields produced by <code>&lt;input&gt;</code> will be available as page $attributes but will all be
      of type String</li>
      <li>the fields produced by <code>&lt;mak:input&gt;</code> are available separately as a <a
        href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/Dictionary.html">Dictionary</a> to
      the handler method</li>
    </ul>
    <pre class="example">&lt;mak:object from="best.Student s, s.person p" where="s=$student"&gt;<br>    &lt;mak:editForm object="p" action="studentView.jsp" method="post"&gt;<br>        name      &lt;mak:input name="name"/&gt;<br>        surname   &lt;mak:input name="surname"/&gt;<br>        gender    &lt;mak:input name="gender" type="tickbox" /&gt;<br>        dob       &lt;mak:input name="birthdate" format="yyyy-MM-dd" /&gt;<br>    &lt;/mak:editForm&gt;<br>&lt;/mak:object&gt;<br></pre>
    <br>
    <p></p>
    <table class="tagParamDef">
      <tbody>
        <tr>
          <th>tag parameter</th>
          <th>description</th>
          <th>comments</th>
        </tr>
        <tr>
          <td><tt>name</tt> <br>
          <tt class="oldfeat">(or field)</tt></td>
          <td>Makumba field (from the edited record or via base pointers or sub-record pointers)</td>
          <td>Fixed, mandatory</td>
        </tr>
        <tr>
          <td style="vertical-align: top;"><tt>nameVar</tt></td>
          <td style="vertical-align: top;">The name of the java variable in which to store the name of the HTML
          input. In multiple forms,&nbsp; there may be more HTML inputs generated by one mak:input, so a suffix is added
          by makumba to the name to generate unique names for each.<br>
          </td>
          <td style="vertical-align: top;">Fixed<br>
          </td>
        </tr>
        <tr>
          <td><tt>value</tt></td>
          <!-- FIXME (fred 2003-10-19): can also be a constant, i think ? -->
          <td>OQL expression relative to enclosing query tags or a <code>$attribute</code> computed previously in
          the page (with <code>&lt;mak:value var=.../&gt;</code> or <code>pageContext.setAttribute(...)</code>), or read
          by in the previous page by an <code>&lt;mak:input /&gt;</code></td>
          <td>Fixed</td>
        </tr>
        <tr>
          <td><tt>type</tt></td>
          <td>HTML INPUT type to be used
          <ul>
            <li>"<code>hidden</code>" works for all fields</li>
            <li>for <code>char[]</code> , type can be "<code>text</code>" or "<code>password</code>", default is "<code>text</code>"</li>
            <li>default type for <code>[set]intEnum</code>, <code>[set]charEnum</code>, <code>ptr</code> and <code>set</code>
            is "<code>select</code>" (dropdown or scroll list depending on <code>size</code>). Alternative is "<code>tickbox</code>"
            (checkboxes or radio buttons). Can be forced to a specific type by using "<code>radio</code>" or "<code>checkbox</code>"</li>
            <li>for <code>set</code>, type can be <code>seteditor</code>, which will create two multiple-select boxes (see an <a
              href="scripts/makumba-JavaScriptChooser.html">example</a>).</li>
            <li>for <code>int</code>, <code>spinner</code> creates a spinner input with increase/decrease buttons; if a <a href="#validation">validation
            definition</a> defines a range for the field, <code>select</code> and <code>radio</code> are will create select boxes and radio buttons.</li>
            <li><code>date</code> is split in 3 inputs, <code>&lt;fieldname&gt;_0</code> (day), <code>_1</code>
            (month), <code>_2</code> (year), and likewise for <code>time</code> elements</li>
            <li>for <code>text</code>, default is "<code>textarea</code>"; "<code>file</code>" will create file
            upload box, and will create supplementary attributes <code>&lt;fieldname&gt;_filename</code>, <code>&lt;fieldname&gt;_contentType</code>
            and <code>&lt;fieldname&gt;_contentLength</code> that have to be handled separately by the handler method</li>
            <li>for <code>file</code>, a file upload box will automatically created, and handling of file name, content type and length will be
            done automatically.</li>
            
          </ul>
          </td>
          <td>Fixed</td>
        </tr>
        <tr>
          <td><tt>display</tt></td>
          <td>If "<code>false</code>", it will not show the &lt;input&gt; but it will expect to read it in the next
          page. This allows the page designer to format the input control manually</td>
          <td>Rtexpr.</td>
        </tr>
        <tr>
          <td><tt>dataType</tt></td>
          <td>The makumba type of the data (needed if there is no value, no default expression for the value, or no
          makumba type associated with an attribute)</td>
          <td>Fixed. Can be <code>char, char[xx], int, date, text, ptr Type, set Type</code></td>
        </tr>
        <tr>
          <td><tt>nullOption</tt></td>
          <td>A text that would be displayed as the "null option" in drop-down boxes, i.e. to add a null value to the other
          possible options. May be used to allow a ptr to be set to null, and/or require a deliberate action from the users to
          select a value, rather leaving the default (first) value selected.</td>
          <td>Fixed. Only for <code>ptr and intEnum types</code></td>
        </tr>
        <tr>
          <td><tt>format</tt></td>
          <td>Format string, according to java.text.SimpleDateFormat <br>
          Can only countain <code>d, M, y, H, m, s</code> formatting chars, and any kind of separators. Ex: <br>
          <code>'the day' dd 'of the month' MMMM 'in the year' yyyy</code>. <br>
          Default is "<code>dd MMMM yyyy</code>"</td>
          <td>Rtexpr. Only for date.</td>
        </tr>
        <tr>
          <td><tt>stepSize</tt></td>
          <td>For <code>int</code> data with <code>type</code> <code>select</code> or <code>radio</code>, the step size defines the steps between
          each option. The default stepsize is 1.</td>
          <td>Rtexpr. Only for int with <code>type=select/radio</code>.</td>
        </tr>
        <tr>
          <td><tt>size</tt></td>
          <td>Size of the input control</td>
          <td>Rtexpr. Only for <code>char[]</code>, <code>int</code> (size of the textbox) and <code>set</code>, <code>ptr</code>
          (height of the select)</td>
        </tr>
        <tr>
          <td><tt>maxLength</tt></td>
          <td>Max length of a text control</td>
          <td>Rtexpr. Only for <code>char[]</code> and <code>int</code>. Defaults to makumba width of the <code>char[]</code></td>
        </tr>
        <tr>
          <td><tt>labelSeparator</tt></td>
          <td>The string that separates the tickbox (radio/check) from the label. Default is <code>" "</code>
          (space). <br>
          The output will be <code>&lt; tick &gt;&lt; labelSeparator &gt;&lt; label &gt;</code></td>
          <td>Rtexpr. Only for <code>type="tickbox"</code>.</td>
        </tr>
        <tr>
          <td><tt>elementSeparator</tt></td>
          <td>The string that separates the different options. Default is <code>" "</code> (space). <br>
          The output will be <code>&lt; [x] label &gt;&lt; elementSeparator &gt;&lt; [x] label &gt;</code></td>
          <td>Rtexpr. Only for <code>type="tickbox"</code>.</td>
        </tr>
        <tr>
          <td><tt>calendarEditor</tt></td>
          <td>Whether to generate code for a calendar editor, defaults to <code>true</code>.<br>
          See the <a href="scripts/makumba-JavaScriptCalendar.html">detailed example</a> for more information.
          <td>Fixed, values are <code>true</code> and <code>false</code>. Only for <code>date</code>.</td>
        </tr>
        <tr>
          <td><tt>calendarEditorLink</tt></td>
          <td>The formatting that appears on the link to the calendar date-choser. <br>
          See the <a href="scripts/makumba-JavaScriptCalendar.html">detailed example</a> for more information.
          <td>Fixed. Only for <code>date</code>.</td>
        </tr>
        <tr class="futfeat">
          <td><tt>(elementSeparatorList)</tt></td>
          <td>The list of strings that separates the different options. Not active by default. The format is "<code>!sep[1]!sep[2]!...!sep[n]!</code>"
          where any character (not appearing inside the separators) can be used as delimiter, e.g. '!'. <br>
          The output will be <br>
          <code>&lt; [x] label &gt;&lt; sep[1] &gt;&lt; [x] label &gt;&lt; sep[2] &gt; ... &lt; [x] label
          &gt;&lt; sep[n] &gt;&lt; [x] label &gt;&lt; sep[1] &gt; ...</code></td>
          <td>Rtexpr. Only for <code>type="tickbox"</code>. Overrides <code>elementSeparator</code> if it exists.</td>
        </tr>
        <tr>
          <td><tt>rows, cols</tt></td>
          <td>Number of textarea rows and columns</td>
          <td>only for <code>text</code></td>
        </tr>
        <tr>
          <td><tt>default</tt></td>
          <td><!--

The character string  to print if the <code>expr</code> results in a NULL value. Default is "" (i.e. zero-length string)

-->FIXME</td>
          <td>Rtexpr</td>
        </tr>
        <tr>
          <td><tt>empty</tt></td>
          <td><!--

The character string to print if the normal printed output would be empty (i.e. zero-length string).

Therefore, this is also used for case <code>expr=NULL<code> and <code>default</code> is not specified.

-->FIXME</td>
          <td>Rtexpr<br>
          </td>
        </tr>
        <!-- generic: -->
        <tr>
          <td><tt>styleId</tt></td>
          <td rowspan="14" colspan="2">Generic html tag attributes, see <a href="#maknew"><code>newForm</code></a>
          </td>
        </tr>
        <tr>
          <td><tt>styleClass</tt></td>
        </tr>
        <tr>
          <td><tt>style</tt></td>
        </tr>
        <tr>
          <td><tt>title</tt></td>
        </tr>
        <tr>
          <td><tt>onClick</tt></td>
        </tr>
        <tr>
          <td><tt>onDblClick</tt></td>
        </tr>
        <tr>
          <td><tt>onKeyDown</tt></td>
        </tr>
        <tr>
          <td><tt>onKeyUp</tt></td>
        </tr>
        <tr>
          <td><tt>onKeyPress</tt></td>
        </tr>
        <tr>
          <td><tt>onMouseDown</tt></td>
        </tr>
        <tr>
          <td><tt>onMouseUp</tt></td>
        </tr>
        <tr>
          <td><tt>onMouseMove</tt></td>
        </tr>
        <tr>
          <td><tt>onMouseOut</tt></td>
        </tr>
        <tr>
          <td><tt>onMouseOver</tt></td>
        </tr>
      </tbody>
    </table>
    <p>Fields of related records can be reference and edited as well, via pointers. In this (somewhat strange)
    example, one can edit the name of the capital city of the country of which person is a citizen, through the person
    edit form :</p>
    <pre class="example">&lt;mak:input name="person.citizenship.capital.name" /&gt;<br></pre>
    <p>Restrictions for different field types:</p>
    <ul>
      <li>fixed fields: cannot be edited</li>
      <li>relational and index pointer: cannot be edited</li>
      <li>timestamps (create and modify): cannot be edited</li>
      <li>subset, subpointer: cannot be edited as a field, only as a separate object</li>
    </ul>
    <h5><a name="choiceDisplay"></a>&lt;mak:option....&gt;...&lt;/mak:option&gt;</h5>
    By default, for pointer and set fields, <code>mak:input</code> will show a choser (selector) that includes the title
    of all possible options, ordered by that title. To change that behavior, the <code>mak:input</code> can include one
    or more <code>mak:option</code>. Options can be repeated using <code>mak:list</code>, <code>c:foreach</code>, and in
    general can appear inside any other tag.
    <p>Text inside <code>mak:option</code> will become an option title. The <code>value</code> attribute will become
    the option.  Text  inside the mak:input that is not inside a mak:option amd is not blank (whitespace) will be assumed to separate groups of options and will be rendered. For options that render HTML SELECTs, this is only accepted for multiple SELECTs which will create several SELECT boxes of equal size, one for each option group.</p>
    <p>If <code>mak:option</code> doesn't have a value indicated, it will produce a nil option. Such nil options
    will be ignored at form submission.</p>
    <p>If an option value appears many times it will only be shown the first time it occurs.</p>
    <p></p>
    <pre class="example">&lt;mak:input name="some" dataType="ptr T"&gt;<br>&lt;mak:option&gt;Please choose:&lt;/mak:option&gt;<br>&lt;mak:list from="T choice" where="someCondition" &gt;<br>    &lt;mak:option value="choice"&gt;&lt;mak:value expr="choice.someField" /&gt;&lt;/mak:option&gt;<br>&lt;/mak:list&gt;<br>&lt;mak:option&gt; -------- separator----------&lt;/mak:option&gt;<br>&lt;mak:list from="T choice" where="someOtherCondition" &gt;<br>   &lt;mak:option value="choice"&gt; &lt;mak:value expr="choice.someField /&gt;&lt;/mak:option&gt;<br>&lt;/mak:list&gt;<br>&lt;/mak:input&gt;<br><br></pre>
    <table class="tagParamDef">
      <tbody>
        <tr>
          <th>tag parameter</th>
          <th>description</th>
          <th>comments</th>
        </tr>
        <tr>
          <td><tt>value</tt> <br>
          </td>
          <td>Value of the option, can be an OQL expression or a $attribute</td>
          <td>Fixed, if not indicated, nil (null option) is default</td>
        </tr>
      </tbody>
    </table>
    <!-- ========================================================= --> 
    <!-- ====================== mak:action ======================= -->
    <h4><a name="action">&lt;mak:action&gt;....&lt;/mak:action&gt;</a></h4>
    <p>If the action URI of a form or deleteLink is more complex, possibly including other makumba tags, the action
    parameter of the form tag can be omitted, and the action URI can be indicated in a <code>mak:action</code>, anywhere
    inside the form tag.</p>
    <p>Example:</p>
    <pre class="example">&lt;mak:editForm object="ins" method="post"&gt;<br>  <b>&lt;mak:action&gt;</b>memberView.jsp?person=&lt;mak:value expr="p"/&gt;<b>&lt;/mak:action&gt;</b><br>...<br>&lt;/mak:editForm&gt;<br></pre>
    <!-- ========================================================= --> 
    <!-- ==================== mak:deleteLink ===================== -->
    <h3><a name="delete">&lt;mak:delete&gt;...&lt;/mak:delete&gt;</a></h3>
    <p>Produces a form or a link to an action page that will delete the object indicated by any of the labels of the mandatory
    enclosing <code>&lt;mak:object&gt;</code> or <code>&lt;mak:list&gt;</code></p>
    <p>Example:</p>
    <pre class="example">&lt;mak:object from="best.Student s, s.languages l" where="s=$student AND l.lang.name=$langname"&gt;<br>  &lt;mak:delete object="l" action="studentView.jsp"&gt;<br>   Delete &lt;mak:value expr="l.lang.name"/&gt;<br>  &lt;/mak:delete&gt;<br>&lt;/mak:object&gt;<br></pre>
    <br>
    <p><b>DEPRECATED:</b> The usage of <code>&lt;mak:deleteLink&gt;</code> is deprecated, and should be replaced by the equivalent:</p>
    <pre class="example">&lt;mak:delete widget="link"&gt;</pre>
    <table class="tagParamDef">
      <tbody>
        <tr>
          <th>tag parameter</th>
          <th>description</th>
          <th>comments</th>
        </tr>
        <tr>
          <td><tt>object</tt></td>
          <td>OQL label of the object to delete</td>
          <td>Fixed</td>
        </tr>
        <tr>
          <td><tt>widget</tt></td>
          <td>UI element of the delete</td>
          <td>Fixed, can be one of <code>button</code> or <code>link</code>; defaults to <code>link</code>.</td>
        </tr>
        <tr>
          <td><tt>preserveWhitespace</tt></td>
          <td>All white space inside a &lt;mak:delete&gt; will be trimmed, unless specifically preserved.</td>
          <td>Fixed, can be one of <code>true</code> or <code>false</code>; defaults to <code>false</code>.</td>
        </tr>
        <tr>
          <td class="futfeat"><tt>(handler)</tt></td>
          <td class="futfeat">the Java class.method that handles the response</td>
          <td>defaults to <code>on_delete+MakumbaTypeOfEditedObject</code>. Arguments: <code>(<a href="api/org/makumba/Pointer.html">Pointer</a>
          object, <a href="api/org/makumba/Attributes.html">Attributes</a> a, <a href="api/org/makumba/Transaction.html">Transaction</a> db)</code>. After deletion, makumba will look for
 		<code>after_delete+MakumbaTypeOfEditedObject</code>. Arguments: <code>(<a href="api/org/makumba/Pointer.html">Pointer</a>
          object, <a href="api/org/makumba/Attributes.html">Attributes</a> a, <a href="api/org/makumba/Transaction.html">Transaction</a> db)</code> and execute it.
          </td>
        </tr>
        <tr>
          <td><tt>action</tt></td>
          <td colspan="2" rowspan="4">see <a href="#maknew"><code>newForm</code></a></td>
        </tr>
        <tr>
          <td><tt>message</tt></td>
        </tr>
        <tr>
          <td><tt>target</tt></td>
        </tr>
        <tr>
          <td><tt>name</tt></td>
        </tr>
        <!-- generic: -->
        <tr>
          <td><tt>styleId</tt></td>
          <td rowspan="14" colspan="2">Generic html tag attributes, see <a href="#maknew"><code>newForm</code></a>
          </td>
        </tr>
        <tr>
          <td><tt>styleClass</tt></td>
        </tr>
        <tr>
          <td><tt>style</tt></td>
        </tr>
        <tr>
          <td><tt>title</tt></td>
        </tr>
        <tr>
          <td><tt>onClick</tt></td>
        </tr>
        <tr>
          <td><tt>onDblClick</tt></td>
        </tr>
        <tr>
          <td><tt>onKeyDown</tt></td>
        </tr>
        <tr>
          <td><tt>onKeyUp</tt></td>
        </tr>
        <tr>
          <td><tt>onKeyPress</tt></td>
        </tr>
        <tr>
          <td><tt>onMouseDown</tt></td>
        </tr>
        <tr>
          <td><tt>onMouseUp</tt></td>
        </tr>
        <tr>
          <td><tt>onMouseMove</tt></td>
        </tr>
        <tr>
          <td><tt>onMouseOut</tt></td>
        </tr>
        <tr>
          <td><tt>onMouseOver</tt></td>
        </tr>
      </tbody>
    </table>
    <p>The response will call the handler method: (the argument names are adapted to the example)</p>
    <pre class="example">on_deleteBestStudentLang(<a href="api/org/makumba/Pointer.html">Pointer</a> lang, <a href="api/org/makumba/Attributes.html">Attributes</a> pageParams, <a href="api/org/makumba/Transaction.html">Transaction</a> db)<br></pre></td>
  </tr>
</table>
</div>



<div id="tab_search" class="content">
<h2><a name="Presentation">JSP taglib - Search</a></h2>
<table width="100%">
  <tr>
    <td valign="top">
    <div class="navbarPage">
    <ul class="navbarPage">
      <li class="section">
        <a href="#search">&lt;mak:searchForm&gt;</a>
        <ul>
          <li class="section"><a href="#criterion">&lt;mak:criterion&gt;</a></li>          
          <li class="section"><a href="#searchField">&lt;mak:searchField&gt;</a></li>          
          <li class="section"><a href="#matchMode">&lt;mak:matchMode&gt;</a></li>
        </ul>
      </li>
      <li class="section"><a href="#resultList">&lt;mak:resultList&gt;</a></li>
    </ul>
    </div>
    </td>
    <td>

    <!-- ========================================================= --> 
    <!-- ==================== mak:searchForm ===================== -->
    <h4><a name="searchForm">&lt;mak:searchForm&gt;...&lt;/mak:searchForm&gt;</a></h4>
    <p>Produces a form to search for records in the database.<br />
    Search forms are in principal related to <a href="tab_forms">mak:forms</a>, i.e. attributes allowed there are also allowed in search forms.
    Additionally, the following attributes are defined.</p>
    <table class="tagParamDef">
      <tbody>
        <tr>
          <th>tag parameter</th>
          <th>description</th>
          <th>comments</th>
        </tr>
        <tr>
          <td><tt>in</tt></td>
          <td>The MDD to search in</td>
          <td>Fixed, mandatory</td>
        </tr>
        <tr>
          <td><tt>name</tt></td>
          <td>Name of the form</td>
          <td>As in mak:forms, but mandatory. Name is used in connection with <a href="#resultList">mak:resultList</a>, and is the prefix for
          several pageContext attributes set, which can be used to perform searching manually.</td>
        </tr>
      </tbody>
    </table>
    <p>Example:</p>
    <pre class="example">
&lt;mak:searchForm in="general.Person" name="searchPerson"&gt;
  ....
&lt;/mak:searchForm&gt;
</pre>

    <p>If you want to do more advanced things in the search page, e.g. sorting of the parameters, you might need to access the pageContext
    attributes describing the search and the results. They are as follows:</p>
    <table class="tagParamDef">
      <thead>
        <tr>
          <th>Attribute name</th>
          <th>description</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td><tt>&lt;searchFormName&gt;Done</tt></td>
          <td>Boolean, saying whether a search was performed (or this is the first time accessing the form). Can be used e.g. as <pre
            class="example">&lt;c:if test="${&lt;searchFormName&gt;Done}"/&gt; Do something when the search was done &lt;/c:if&gt;</pre></td>
        </tr>
        <tr>
          <td><tt>&lt;searchFormName&gt;QueryString</tt></td>
          <td>The query string containing the values for the form fields filled in in the search.<br />
          Use this e.g. in as <pre class="example">&lt;a href="searchPage.jsp?${&lt;searchFormName&gt;QueryString}&amp;sortBy=name"&gt;</pre> when you
          want to provide sorting by a specific field.</td>
        </tr>
        <tr>
          <td><tt>&lt;searchFormName&gt;VariableFrom</tt></td>
          <td>The additional data definitions needed to perform the query, will be used by <a href="#resultList">mak:resultList</a> in the
          variableFrom=".." attribute.</td>
        </tr>
        <tr>
          <td><tt>&lt;searchFormName&gt;Where</tt></td>
          <td>The filter conditions for the matching records, will be used by <a href="#resultList">mak:resultList</a> in the where=".." attribute.</td>
        </tr>
      </tbody>
    </table>

    <!-- ========================================================= --> 
    <!-- ==================== mak:criterion ===================== -->
    <h4><a name="criterion">&lt;mak:criterion&gt;...&lt;/mak:criterion&gt;</a></h4>
    <p>Adds a search criterion to the form. This does not create any inputs, but should be used in combination with &lt;mak:searchField&gt; </p>
    <table class="tagParamDef">
      <thead>
        <tr>
          <th>tag parameter</th>
          <th>description</th>
          <th>comments</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td><tt>fields</tt></td>
          <td>The MDD fields to apply this criterion upon</td>
          <td>Fixed, mandatory; for multiple fields, provide a comma-separated list.<br />
          Note that you can search also on the <a href="#DefaultFields">default fields</a> TS_create and TS_modify; further, you can search on fields
          in referred fields, i.e. <code>ptr</code> and <code>set</code> types.</td>
        </tr>
        <tr>
          <td><tt>isRange</tt></td>
          <td>Toggles range searching on the field(s)</td>
          <td>Fixed. Values are <code>true</code> or <code>false</code>; defaults to <code>false</code>.</td>
        </tr>
        <tr>
          <td><tt>matchMode</tt></td>
          <td>Defines how the search terms shall be matched. Allowed values depend on the data types: 
            <ul>
              <li>for string matches, i.e. char and text: 'contains', 'equals', 'begins', 'ends'</li>
              <li>for range matches, i.e. int, real and date: 'between', 'betweenInclusive'</li>
              <li>for number comparisons, i.e. int and real: 'equals', 'lessThan', 'greaterThan'</li>
              <li>for date comparisons: 'equals', 'before', 'after'</li>
            </ul></td>
          <td>Fixed. Defaults to 'equals' for string, number and date comparisons, and 'betweenInclusive' for range comparisons.</td>
        </tr>
      </tbody>
    </table>
    <p>Example:</p>
    <pre class="example">
&lt;mak:searchForm in="best.Student" name="searchPerson"&gt;
  &lt;mak:criterion fields="name"&gt; ... &lt;/mak:criterion&gt;
&lt;/mak:searchForm&gt;
</pre>
    <div class="note futfeat">In the future, a &lt;mak:criterion .. /&gt; without a body might by default behave like having a single &lt;mak:searchField/&gt; inside
    </div>

    <!-- ========================================================= --> 
    <!-- ==================== mak:searchField ==================== -->
    <h4><a name="searchField">&lt;mak:searchField/&gt;</a></h4>
    <p>Enclosed inside a &lt;mak:criterion&gt;, generates an input for that criterion. This tag is based on the <a href="#input">&lt;mak:input/&gt;</a> tag, and provides additionally the following attributes:</p>
    <table class="tagParamDef">
      <tbody>
        <tr>
          <th>tag parameter</th>
          <th>description</th>
          <th>comments</th>
        </tr>
        <tr>
          <td><tt>forceInputStyle</tt></td>
          <td>Changes the style/type of the input as it would be normally computed for the data type.</td>
          <td>
            Fixed; applicable for the following data types:
            <ul>
              <li>text: '<code>input</code>' forces an &lt;input&gt; tag rather than a &lt;textArea&gt;.</li>
              <li>ptr: '<code>multiple</code>' forces a multiple-select rather than a single-select, and check-boxes rather than radio-buttons.</li>
              <li>set: '<code>single</code>' forces a single-select rather than a multiple-select, and radio-buttons rather than check-boxes.</li>
            </ul>
          </td>
        </tr>
      </tbody>
    </table>
    <p>Example:</p>
    <pre class="example">
&lt;mak:searchForm in="best.Student" name="searchPerson"&gt;
  &lt;mak:criterion fields="name"&gt; &lt;mak:searchField /&gt; &lt;/mak:criterion&gt;
  &lt;mak:criterion fields="place"&gt; &lt;mak:searchField forceInputStyle="single" /&gt; &lt;/mak:criterion&gt;  
&lt;/mak:searchForm&gt;
</pre>

    <!-- ========================================================= --> 
    <!-- ==================== mak:matchMode ====================== -->
    <h4><a name="matchMode">&lt;mak:matchMode/&gt;</a></h4>
    <p>Enclosed inside a &lt;mak:criterion&gt;, generates a select input to specify how that criterion should be matched. Applies only to char, text for string matching; int, real for number comparisons; date types for date comparisons; and int, real and date for range matching.</p>
    <table class="tagParamDef">
      <tbody>
        <tr>
          <th>tag parameter</th>
          <th>description</th>
          <th>comments</th>
        </tr>
        <tr>
          <td><tt>type</tt></td>
          <td>
            HTML INPUT type to be used:
            <ul>
              <li>"select" (drop-down).</li>
              <li>"radio" (radio buttons).</li>
            </ul>
          </td>
          <td>Fixed. Defaults to 'select'.</td>
        </tr>
        <tr>
          <td><tt>matchModes</tt></td>
          <td>
            Defines how the search terms shall be matched. Comma-separated list of operations; allowed values depend on the data types: 
            <ul>
              <li>for string matches, i.e. char and text: 'contains', 'equals', 'begins', 'ends'</li>
              <li>for range matches, i.e. int, real and date: 'between', 'betweenInclusive'</li>
              <li>for number comparisons, i.e. int and real: 'equals', 'lessThan', 'greaterThan'</li>
              <li>for date comparisons: 'equals', 'before', 'after'</li>
            </ul>
          </td>
          <td>Fixed. Defaults to 'equals' for string, number and date comparisons, and 'betweenInclusive' for range comparisons.</td>
        </tr>
        <tr>
          <td><tt>defaultMatchMode</tt></td>
          <td>The default match-mode to be selected when the form is first loaded.</td>
          <td>Fixed. See 'matchModes' for allowed values.</td>
        </tr>
      </tbody>
    </table>
    <p>Example:</p>
    <pre class="example">
&lt;mak:searchForm in="best.Student" name="searchPerson"&gt;
  &lt;mak:criterion fields="name"&gt; &lt;mak:matchMode matchModes="contains, equals, begins, ends"&gt; &lt;mak:searchField /&gt; &lt;/mak:criterion&gt;
&lt;/mak:searchForm&gt;
</pre>


    <!-- ========================================================= --> 
    <!-- ==================== mak:resultList ===================== -->
    <h4><a name="matchMode">&lt;mak:resultList&gt;...&lt;/mak:resultList&gt;</a></h4>
    <p>Similar to, and based on the &lt;mak:list&gt;, this tag automatically iterates over the results from a specified search form. On top of &lt;mak:list&gt;, the following attributes are available:</p>
    <table class="tagParamDef">
      <tbody>
        <tr>
          <th>tag parameter</th>
          <th>description</th>
          <th>comments</th>
        </tr>
        <tr>
          <td><tt>resultsFrom</tt></td>
          <td>The name of the search form the results are taken from.</td>
          <td>Fixed</td>
        </tr>
      </tbody>
    </table>
    <br>
    <div class="note">The name of the object selected in the list is fixed to 'o', sub-sets get selected as 'o_subFieldName'.</div>
    <p>Example:</p>
    <pre class="example">
&lt;mak:resultList resultsFrom="searchPerson"&gt;
  Name: &lt;mak:value expr="o.name"/&gt; &lt;br/&gt;
&lt;/mak:resultList&gt;
</pre>
    </td>
  </tr>
</table>
</div> 


<div id="tab_bl" class="content">
<h2><a name="Business">Business Logic (BL)</a></h2>
<table width="100%">
  <tr>
    <td valign="top">
    <div class="navbarPage">
    <ul class="navbarPage">
      <li class="section"><a href="#Attributes">Attributes</a></li>
      <li class="section"><a href="#javahand">Java&nbsp;Handler classes</a></li>
      <li><a href="#Login">Login, &lt;mak:login&gt;, &lt;mak:logout/&gt;</a></li>
    </ul>
    </div>
    </td>
    <td>
    <h3><a name="Attributes">Attributes</a></h3>
    <p>Java Server Pages use attributes to keep the state of the application. Makumba builds upon that its own
    notion of Attributes that keep the read-only state of a makumba task. They represent the "environment" of that
    makumba task. The typical example is a JSP page during execution, with its HTTP and session parameters as
    attributes. Since other kinds of attributes are possible, the attribute specification is kept HTTP-independent.
    Makumba BL code sees the attributes as an <a href="api/org/makumba/Attributes.html"><code>org.makumba.Attributes</code></a>
    object.</p>
    <h3><a name="javahand">Java handler classes</a></h3>
    <p>Java handler classes are classes that implement the "business logic" of the organisation. Every makumba page
    will look for a handler, and will call its methods when needed. Check also the &lt;mak:newForm&gt; to know <a
      href="#handler_methods">which methods are called</a>. <span style="font-weight: bold;">If a handler class
    exists, then some operations cannot be performed if these methods are not defined in the handler class.</span><br>
    </p>
    <h4>Handler Discovery</h4>
    <p>Each page will determine its handler class on first access, after being compiled. If the class changes on
    disk, a webapp reload is generally needed for the new class to take effect.</p>
    <p>The handler is 'discovered' by decomposing the full path of the JSP page, and finding a class with a matching
    name. Decomposition breaks the full path at every capital letter, or forward slash. For example, with the page path
    <b><code>/student/mycv/indexPersonal.jsp</code></b>, the following criteria are applied, in order:</p>
    <table class="tagParamDef">
      <tbody>
        <tr>
          <th>criterium</th>
          <th>Java classes checked for</th>
        </tr>
        <tr>
          <td>page name</td>
          <td><tt>StudentMycvIndexPersonalLogic</tt></td>
        </tr>
        <tr>
          <td>caps parts of page/directory name</td>
          <td><tt>StudentMycvIndexLogic</tt></td>
        </tr>
        <tr>
          <td>directory name</td>
          <td><tt>StudentMycvLogic</tt></td>
        </tr>
        <tr>
          <td>parent directory name(s)</td>
          <td><tt>StudentLogic</tt> <br>
          <tt>Logic</tt></td>
        </tr>
      </tbody>
    </table>
    <p>The class name prefix (e.g. java package name) can be regulated per parts of the site in a file called <b>MakumbaController.properties</b>
    which can be found in the CLASSPATH (just like MakumbaDatabase.properties). For example, the file can contain:</p>
    <pre class="example">/student=org.eu.best<br>/makumba=org.makumba<br>/=test<br></pre>
    <p></p>
    <table class="tagParamDef">
      <tbody>
        <tr>
          <th>path</th>
          <th>Java classes checked for</th>
        </tr>
        <tr>
          <td><tt>/student/mycv/index.jsp</tt></td>
          <td><tt>org.eu.best.MycvIndexLogic</tt> <br>
          <tt>org.eu.best.MycvLogic</tt> <br>
          <tt>org.eu.best.Logic</tt></td>
        </tr>
        <tr>
          <td><tt>/makumba/tests/x.jsp</tt></td>
          <td><tt>org.makumba.TestsXLogic</tt> <br>
          <tt>org.makumba.TestsLogic</tt> <br>
          <tt>org.makumba.Logic</tt></td>
        </tr>
        <tr>
          <td><tt>/some.jsp</tt></td>
          <td><tt>test.SomeLogic</tt> <br>
          <tt>test.Logic</tt></td>
        </tr>
      </tbody>
    </table>
    <p class="futfeat">There are good reasons to take into account the name of the response page of a form when
    looking for the business logic. Still, <span style="font-weight: bold;">it is the name of the page that
    contains the form which matters</span> <span style="font-style: italic;">not </span>the name of the action page. It is good
    practice for both pages to actually have the same handler class.</p>
    <p>All methods of the handlers are http-independent. Methods are non-static, so the handler classes can use
    inheritance to their advantage. Still, handler classes are singletons (only one instance of a certain class in a
    JVM). For example, the validation of a form can be in a class that is closer to the actual JSP application (view
    level) while the more view-independent methods can be in the parent of that class. For example:</p>
    <pre class="example">org.eu.best.minerva.StudentHandler extends org.eu.best.StudentHandler<br></pre>
    <h4>Role of Java handlers</h4>
    <ol>
      <li><b>find attributes</b> unknown by pages. e.g. <pre class="example">&lt;mak:object from="best.Student stud" where="stud=$student"&gt; ...&lt;/mak:object&gt;<br></pre>
      <p>If the <code>$student</code> attribute is not known in the page (from a http argument) or in the session,
      the <code>find{AttributeName}(<a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/Dictionary.html">Dictionary</a> existingAttributes, <a href="api/org/makumba/Transaction.html">Transaction</a> d, String expression)</code> method is
      called for the Handler object. In this case findStudent(). The handler has to compute the attribute, based on
      existing attributes, making DB accesses.</p>
      <div class="note">The find{AttributeName} method's name is constructed literally from the name of the
      attribute (capitalising only the first letter), so dots and other illegal characters for java identifier names,
      are not to be used. Also, one shouldn't use 2 attribute names that differ only in the capitalisation of the first
      letter.</div>
      <p>For example "<code>lbg.$lbg_order</code>" (in an example elsewhere in the specs), will generate a call <code>findLbg_order(otherAttributes,
      db)</code> and the Java handler will return the default ordering for LBGs (say "name").</p>
      <p>If the attribute is computed successfully, it is associated with the session (i.e. set as JSP attribute in
      session scope)</p>
      <p>If not, an exception will be thrown (typically <a href="api/org/makumba/UnauthenticatedException.html"><code>org.makumba.UnauthenticatedException</code></a>),
      and the engine will act accordingly (i.e. ask for authentication).</p>
      </li>
      <li><b>execute action methods</b> in response to makumba forms. See <a href="#forms">makumba forms and
      actions</a> below.
      <p></p>
      </li>
      <li class="futfeat">( later: return query parts, as methods. e.g. <code>&lt;mak:value
      expr="lbg.$title()" /&gt;</code> will generate a call to method <code>BestInternalLbgTitle(lbg)</code> which can return
      an OQL expression "<code>concat(lbg.id, \"-\" lbg.name)</code>" (such methods can be put directly in the Makumba
      data definitions) For now, OQL only accepts count() and sum(), but that can be easily fixed, till then, the method
      can be replaced by hand: <code>&lt;mak:value expr="lbg.id"/&gt;-&lt;mak:value expr="lbg.name"/&gt;</code> )</li>
    </ol>
    <h4>Handler Initialization</h4>
    <p>Whenever a handler is used in a new context (i.e. with a different set of attributes, e.g. a new page
    access), a method called <code>checkAttributes(<a href="api/org/makumba/Attributes.html">Attributes</a> a, <a href="api/org/makumba/Transaction.html">Transaction</a> db)</code> is looked for and executed, if it
    is defined.</p>
    <p><b><code>checkAttributes</code></b> can perform sanity checks for attributes used in the respective logic (in
    case of mismatches, <a href="api/org/makumba/UnauthorizedException.html"><code>org.makumba.UnauthorizedException</code></a>
    is usually thrown), can load attributes that are absolutely needed for page execution (<span class="oldfeat">formerly
    given by the requiredAttributes() method</span>), etc.</p>
    <h4>Transaction provider configuration</h4>
    <p>Most handlers provide a <a href="api/org/makumba/Transaction.html">Transaction</a> that can be used to perform addition database operations in the Business Logic.
    The class of this handler can be configured by providing a getTransactionProvider() String, that returns the fully-qualified name of the transaction provider implementation. For the moment, possible values are <code>org.makumba.db.makumba.MakumbaTransactionProvider</code> (native Makumba database layer) and <code>org.makumba.db.hibernate.HibernateTransactionProvider</code> (Hibernate-driven database layer)</p>
    <h3><a name="Login">Login</a></h3>
    Login is done as a result of a missing attribute (possibly invoked in <b><code>checkAttributes</code></b>), when a <code>find{AttributeName}</code>
    method is called. The missing attribute is the principal that needs to log in.
    <p>If the attribute cannot be found due to wrong login information, <a
      href="api/org/makumba/UnauthenticatedException.html"><code>org.makumba.UnauthenticatedException</code></a> is
    usually thrown.</p>
    <p>The principal (the person who logs in) can have more members (e.g. group, Lbg, Company representatives). E.g.
    the findCompany() method will check to see if the authentication (email_address and password) corresponds to any
    company representative of that company. If yes, it will return that company.</p>
    <p class="futfeat">Login can be done in 2 ways:</p>
    <ol>
      <li class="futfeat">(Http basic authentication login: will set the attributes $username, $password )</li>
      <li>cookie login: done in a page called <code>login.jsp</code>, in the same directory or (if missing) in any
      of the parents. It should contain at least: <pre class="example">&lt;mak:login&gt;<br>  &lt;input type=text name=username&gt;<br>  &lt;input type=password name=password&gt;<br>  &lt;input type=submit&gt;<br>&lt;/mak:login&gt;<br></pre>
      <p>The login form will pass further (as hidden arguments) all the http parameters it got. Note that <code>&lt;mak:login&gt;</code>
      is only needed upon automatic login (a page displayed when the user requested another page, that needs
      authentication). If you wish to ask for login manually in a startup page, a normal HTML form is enough.</p>
      </li>
    </ol>
    <p>To cancel out a certain attribute, in order to produce a new login, the logout tag is available</p>
    <pre class="example">&lt;mak:logout actor="student"/&gt;<br></pre>
    <p>You can remove (cancel-out, logout) multiple attributes from the session by using <code>&lt;mak:logout
    actor="attribute name"&gt;</code> several times and/or by using the star (*) wildcard, e.g.:</p>
    <pre class="example">&lt;mak:logout actor="demo_*"/&gt; (attributes whose names start with "demo_")<br>&lt;mak:logout actor="*app"/&gt; (attributes whose names end with "app")<br>&lt;mak:logout actor="*"/&gt; (all attributes; this "invalidates" the session)<br></pre>
    <p></p>
    <div class="futfeat">(Later on, logout request might be done in the business logic, with a method <code>deleteAttributes(param)</code>
    that can accept either a String (with optional '*') or a String[]. )
    <p>(Later: to accomodate servers that don't do session tracking, login can be done by a query condition rather
    than by doing a query (once per session) to find an attribute. This way, it won't need to do a query (to check the
    authentication) at every access, but that condition will make sure that authentication is done. )</p>
    <p><tt>(&lt;mak:object from="best.Student stud" where ="stud.$login()"&gt; ...&lt;/mak:object&gt;</tt> <br>
    then methodBestSudentLogin("stud") will return "stud.auth.email=$username AND stud.auth.password=$password" <br>
    This can be used for http authentication with no session tracking. )</p>
    <p>(Later: if an attribute has multiple values, a <code>choose{AttributeName}.jsp</code> page is shown. For
    example, a super user (for that area) can choose to act as any student, Lbg, or company... A student member of more
    local Vivaldi teams can choose to act for any of the viv teams, etc. )</p>
    </div>

    </td>
  </tr>
</table>
</div>





<div id="tab_summary" class="content">
<h2><a name="PresentationSummary">Presentation and internal representation summary</a></h2>
<table width="100%">
  <tr>
    <td valign="top"></td>
    <td>
    <p>This table describes the data types and their default user interface representation. That user interface can
    be altered with the <a href="#Presentation">Presentation language</a> described below. Orientative SQL and Java
    types are presented.</p>
    <br>
    &nbsp;
    <table class="tagParamDef">
      <tbody>
        <tr>
          <th>Data definition type</th>
          <th>Default edit user interface</th>
          <th>Relational database type (orientative)</th>
          <th>Java type (orientative)</th>
        </tr>
        <tr>
          <td>type (table)</td>
          <td><span class="futfeat">(list of records, with add, delete, edit controls; titles emphasized)</span></td>
          <td>table</td>
          <td><br>
          </td>
        </tr>
        <tr>
          <td>record</td>
          <td><span class="futfeat">(all fields, as shown below)</span></td>
          <td>record</td>
          <td><a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/Dictionary.html">java.util.Dictionary</a></td>
        </tr>
        <tr>
          <td>int&nbsp;</td>
          <td>text field <span class="futfeat">(or slider)</span></td>
          <td rowspan="2">integer</td>
          <td rowspan="2">java.lang.Integer</td>
        </tr>
        <tr>
          <td>int{}&nbsp;</td>
          <td>dropdown choice or radio button</td>
        </tr>
        <tr>
          <td>real</td>
          <td>text field</td>
          <td>double</td>
          <td>java.lang.Double</td>
        </tr>
        <tr>
          <td>char[]&nbsp;</td>
          <td>text field</td>
          <td rowspan="2">limited char</td>
          <td rowspan="2">java.lang.String</td>
        </tr>
        <tr>
          <td>char{}</td>
          <td>dropdown choice or radio button</td>
        </tr>
        <tr>
          <td>text</td>
          <td>text area</td>
          <td>unlimited characters</td>
          <td>org.makumba.Text</td>
        </tr>
        <tr>
          <td>binary</td>
          <td>binary area</td>
          <td>unlimited byte</td>
          <td>org.makumba.Text</td>
        </tr>
        <tr>
          <td>date</td>
          <td>date</td>
          <td>date and time</td>
          <td>java.util.Date</td>
        </tr>
        <tr>
          <td>ptr</td>

          <td>dropdown select of record titles. See the <a href="scripts/makumba-javascript.html">example</a> for
          set/ptr choosers with Makumba.</td>
          <td>preferably a long (foreign index)</td>
          <td rowspan="4"><a href="api/org/makumba/Pointer.html">org.makumba.Pointer</a></td>
        </tr>
        <tr>
          <td>xx=ptr <br>
          xx-&gt;...</td>
          <td><span class="futfeat">(the record, if any)</span></td>
          <td>preferably a long (foreign index) <br>
          + table</td>
        </tr>
        <tr>
          <td>file</td>
          <td>file upload</td>
          <td>preferably a long (foreign index) <br>
          + table</td>
        </tr>
        <tr>
          <td>Index field</td>
          <td>(nothing)</td>
          <td>preferably long, <br>
          autoincrement, or other unique</td>
        </tr>
        <tr>
          <td>creation date <br>
          modification date</td>
          <td>date, not editable</td>
          <td>timestamp</td>
          <td>java.sql.Timestamp</td>
        </tr>
        <tr>
          <td>set</td>

          <td>multiple choice of record titles. See the <a href="scripts/makumba-javascript.html">example</a> for
          set/ptr choosers with Makumba.</td>
          <td>table with ptrRel to the parent table and ptr to the foreign table</td>
          <td>java.util.Vector of <a href="api/org/makumba/Pointer.html">org.makumba.Pointer</a></td>
        </tr>
        <tr>
          <td>xx=set <br>
          xx-&gt; ...</td>
          <td><span class="futfeat">(like a table, under current record)</span></td>
          <td>table with ptrRel to the parent table, and the rest of the fields</td>
          <td><br>
          </td>
        </tr>
        <tr>
          <td>set int{ ...}</td>
          <td>multiple choice from values</td>
          <td>table with ptrRel to the parent table, and an int field</td>
          <td>java.util.Vector of java.lang.Integer</td>
        </tr>
        <tr>
          <td>set char{ ...}</td>
          <td>multiple choice from values</td>
          <td>table with ptrRel to the parent table, and a char field</td>
          <td>java.util.Vector of java.lang.String</td>
        </tr>
      </tbody>
    </table>
    </td>
  </tr>
</table>
</div>

<script type="text/javascript">
   makeFooter("$Id$");
</script>

<script language="javascript">
<!-- // If JS is enabled activate default tab, otherwise - all will be shown
initiateTab();
//-->
</script>

</body>
</html>
